We are about to switch to a new forum software. Until then we have removed the registration on this forum.
There was a recent change of the dataPath()
function and it should work if you place your video inside the data folder. When the Android app is built, dataPath()
works along the same lines as getAssets()
. I haven't had the chance to test your code but I would like to suggest you try getAssets()
instead for now. Please check this post and see if it works for you:
https://discourse.processing.org/t/tracking-high-score-for-android/678/4
Kf
It's quite a long set of code, actually, but I'll still paste it in, because someone might need it later. It also requires an additional "palette" file, so I'll link that too:
https://www.dropbox.com/s/r3u1gb8cm234qc4/palette?dl=0
byte[] byte2(int a){ //Converts an int into 4 bytes packed into an array
byte[] ret = new byte[4];
ret[0]=(byte)((a)&0xFF);
ret[1]=(byte)((a>>8)&0xFF);
ret[2]=(byte)((a>>16)&0xFF);
ret[3]=(byte)(a>>24&0xFF);
return ret;
}
byte[] append(byte[] in,byte[] more){ //Allows appending an array of bytes to another array of bytes
for(int i=0;i<more.length;i++){
in=append(in,more[i]);
}
return in;
}
int bitpos(int x,int y,int width){ //Converts input X Y coordinates into a byte number
return x+y*(bitoffset(width));
}
int bitx(int in,int width){ //Converts a byte number into an X coordinate
return in%(bitoffset(width));
//return 0;
}
int bity(int in,int width){ //Converts a byte number into an Y coordinate
return floor(in/(bitoffset(width)));
}
boolean bitgood(int in,int width){ //Can I write in this byte, or it's one of those 4 spacing bytes at the end of each horisontal line?
return in%(bitoffset(width))<width;
}
int bitoffset(int width){ //To account for these 4 additional spacing bytes at the end of each horisontal line.
return (((width - 1) / 4) + 1) * 4;
}
int unsignbyte(byte in){ //Converts a byte into int as if it were unsigned
return (int)in&0x7F+(in<0?128:0);
}
void MakeBMP(String path,PImage img){ ///Grabs a path and an image, and saves it as an 8-bit BMP file with palette from dataPath("palette") file.
int width=img.width;
int height=img.height;
//This is based on this: http://www.dragonwins.com/domains/getteched/bmp/bmpfileformat.htm
byte[] test={66,77}; // 0 "BM" header.
test=append(test,byte2(0)); // 2 File size. We are going to fill this later.
test=append(test,byte2(0)); // 6 Reserved.
test=append(test,byte2(1024+54)); //10 Pixel data start offset. ok.
test=append(test,byte2(40)); // 14 Header size.
test=append(test,byte2(width)); // 18 Width.
test=append(test,byte2(height)); // 22 Height.
test=append(test,byte(1)); // 26 Amount of images in this image. ._.
test=append(test,byte(0)); // 27 2 bytes for amount of images here. ._.
test=append(test,byte(8)); // 28 Bits per pixel. This is 8 bit bmp generator code thing, so not much to say here.
test=append(test,byte(0)); // 29 Bits per pixel. Needs 2 bytes.
test=append(test,byte2(0)); // 30 Compression type. I don't like compression.
test=append(test,byte2(0)); // 34 Image size. Really matters only if compressed, so I'll just 0 here.
test=append(test,byte2(0));// 38 Preferred X printing resolution. We aren't going to print sprites!
test=append(test,byte2(0));// 42 Preferred Y printing resolution. We aren't going to print sprites!
test=append(test,byte2(0));// 46 Number of used Color Map entries.
test=append(test,byte2(0));// 50 Number of significant Color Map entries.
//54 Color table now? Oh snap...
byte[] Palette=loadBytes(dataPath("palette"));
for(int i=54;i<54+1024;i++){ //Loop to iterate through the whole palette
//test=append(test,byte(i-54)); //blue
//test=append(test,byte(0)); //green
//test=append(test,byte(0)); //red
//test=append(test,byte(0)); //zero
test=append(test,Palette[i]); //Just grab everything from the palette file
}
//1078 AND EVEN COLOR DATA?! OHH SNAAAAP!!
for(int i=0;i<(width+4)*height;i++){ // Loop to iterate for every input image pixel (+4 is because every horisontal line has 4 additional bytes at the end, which are usually all 0, I guess spacing different lines out.
//This next bit of code grabs the color from the input image and compares it to all colors in the palette until it finds the one that is closest, and assigns that.
color pixel=img.get(bitx(i,width),height-bity(i,width)-1); //Grab matching image pixel
if(alpha(pixel)==255&bitgood(i,width)){ //If it's transparent just use first color in the palette (which is R G B 255 0 255 in the included palette). Or if it's a spacing byte then also don't bother.
float diffbest=99999999; //How different is the best matching color in the palette from the current image pixel?
int best=0; //What color in the palette is the best matching to the current image pixel?
for(int u=0;u<255;u++){ //Iterate through all palette colors
float diff=abs(unsignbyte(test[56+u*4])-red(pixel))+abs(unsignbyte(test[55+u*4])-green(pixel))+abs(unsignbyte(test[54+u*4])-blue(pixel)); //Difference between current img pixel and current pal color
if(diff<diffbest){ //If this palette color's better
diffbest=diff; best=u; //Remember it
}
if(diff==0){u=255;} //If it matches perfectly to the input image color, why bother with all of the other colors in the palette?
}
test=append(test,byte(best));
}else{test=append(test, byte(0));} //Just 0.
}
test[2]=byte2(test.length-54)[0]; // 2 File size
test[3]=byte2(test.length-54)[1]; // 2 File size
test[4]=byte2(test.length-54)[2]; // 2 File size
test[5]=byte2(test.length-54)[3]; // 2 File size
saveBytes(path,test); //Allright, work's done! Everyone go home!
}
I have a small .bmp file that weighs 1296 bytes. When I do this string, it saves it as a .bmp files that weighs 558 bytes:
loadImage(dataPath("test.bmp")).save(dataPath("test2.bmp"));
I assume this is because it saves it with a different bit depth. What can I do to make it save with bit depth of the original image? I need it to have same everything as the original file for technical reasons. Here's my test file: https://www.dropbox.com/s/1b08oe0j3w8kc78/test.bmp
And here's what I get: https://www.dropbox.com/s/kqjulvbhai9t0qm/test2.bmp
edit: I'm not looking for just copying the image, which obviously can be done by copying the file over. I want to be able to edit them with functions like .get() and .set() and then save the result in the same format and with same characteristics as the input file.
edit2: Also I'm not looking for any size or efficiency advantages at all - an old videogame I'm working with just refuses to work with test2.bmp, while it can take test.bmp perfectly. And, from a bit of testing with different files I've concluded that the difference between input and output file that Processing introduces is what causes it.
Not sure if doing this through a different thread will help. If you are loading the videos, I would say that assigning the videos, the way you do, should work, assuming your computer can handle loading these many videos.
I have to say I am not sure your approach works at the end. You are assigning VideoM objects from your video list but I don't think you are ensuring the same video is not picked. Why is this important? Well, because you are calling jump(). If two VideoM objects are handling the same video, you are calling jump on the same handle. it is very likely only the last jump is applied and both handles would display the same video.
I have to say your code comments are missing? It is hard to understand what you are trying to accomplish in certain parts of your code. Adding comments would help. Also, the name of your arrays are not the best. For this bit of code, the array functionality is lost between the lines. Using better names like masterVideolist would make your code easier to follow.
I have two questions:
1. When the timer ends, do you change one video or all the videos?
2. The display function manages some tinting. What does it do? I can see the alphai
counter going up and down but I didn't understand what you want to do.
I have added some code below but it is not a solution. I just want to capture some changes I did and I will change it as soon as you answer my questions.
Kf
import processing.video.*;
final int NSHOWVIDEOS=5;
File path;
String[] files;
int numfiles = 0;
int timer = -5000;
int tcontrol= 2000;
boolean bStop, bColor=true;
boolean bSave=false, bVidO=false;
VideoM[] v = new VideoM[NSHOWVIDEOS];
Movie[] videoStack;
void setup() {
size(1920, 1080);
frameRate(60);
files = files();
numfiles = files.length;
if (numfiles>11) numfiles=11;
loadvideos(); //Inits videoStack
for (int i = 0; i < NSHOWVIDEOS; i++) {
v[i] = new VideoM(i);
}
}
void draw() {
background(0);
for (int i = 0; i <NSHOWVIDEOS; i++) {
v[i].display();
}
if ((millis() - timer) > tcontrol) {
thread("newvideo");
timer = millis();
tcontrol= int(random(2, 6))*1000;
}
}
void movieEvent(Movie m) {
m.read();
}
void keyPressed()
{
int k = keyCode;
// reset all videos
if (key == 'n' || key == 'N') {
newset();
}
}
//=====================================================
void newset() {
for (int i = 0; i < NSHOWVIDEOS; i++) {
println(i);
v[i].newvid();
}
}
//=====================================================
void newvideo() {
int i = int(random(NSHOWVIDEOS));
//v[i].nuevovid(this);
v[i].cambiavid();
}
//=====================================================
void loadvideos() {
videoStack = new Movie[numfiles];
for (int i=0; i<numfiles; i++) {
String video= files[i]; //files[int(random(numfiles))];
videoStack[i] = new Movie(this, video);
videoStack[i].play();
videoStack[i].pause();
println ("Loading ", video);
}
}
//=====================================================
// load files in data
String[] files() {
// The data path of the folder to look in (write your own)
java.io.File folder = new java.io.File(dataPath(""));
// let's set a filter (which returns true if file's extension is .jpg)
java.io.FilenameFilter pngFilter = new java.io.FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".mp4");
}
};
// list all the folders inside the main directory
String[] listFolders = folder.list(new java.io.FilenameFilter() {
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
}
);
// list the files in the data folder, passing the filter as parameter
String[] filenames = folder.list(pngFilter);
return(filenames);
}
//=====================================================
class VideoM {
Movie m;
String video;
int x, y, w, h;
int alpha;
int alphai;
int fadeout=0;
int idx;
VideoM(int aidx) {
idx=aidx;
newvid();
}
void newvid() {
m=null;
int j=idx;//int(random(numfiles));
println("cambio: ", j);
m = videoStack[j];
m.loop();
genera();
m.jump(random(m.duration()));
println(Thread.currentThread());
}
void genera() {
x=int(random(50, width/2+width/4));
y=int(random(50, height/2+height/4));
w=int(random(280, 820));
h=int(w/1.88);
alpha=int(random(100, 255));
alphai=0;
}
void display() {
tint(255, alphai);
if (fadeout==0) {
alphai++;
if (alphai>alpha) alphai=alpha;
} else {
alphai--;
if (alphai<0) {
alphai=0;
fadeout=0;
this.newvid();
}
}
if (frameCount > 1) {
//image(m, x, y, w, h);
image(m, x, y);
}
}
void cambiavid() {
fadeout=1;
}
}
Hello! This script only requires a bunch of .mp4s in the data folder. You'll see a collage of 9 videos (or duplicates) in different positions and transparencies. The thing runs ok but even pre-loading the videos at the beginning every time there's a change/swap in one of the videos (around every 4 seconds) the whole thing freezes for a sec, sometimes (try to use mp4s of different sizes).
I tried to use the thread() command in the switching of the videos but nothing happened. I put a println to see the thread but alway show the main thread, I really don't know if I'm doing this ok..
Thanks a LOT for any help!
import processing.video.*;
File path;
String[] files;
int numfiles = 0;
int timer = -5000;
int tcontrol= 2000;
int numVideos=9;
VideoM[] v = new VideoM[numVideos];
Movie[] vv;
void setup(){
size(1920, 1080, P2D);
frameRate(60);
files = files();
numfiles = files.length;
if (numfiles>11) numfiles=11;
loadvideos();
for(int i = 0;i < numVideos;i++){
v[i] = new VideoM();
}
}
void draw() {
background(0);
for(int i = 0; i <numVideos; i++){
v[i].display();
}
if ((millis() - timer) > tcontrol) {
thread("newvideo");
timer = millis();
tcontrol= int(random(2,6))*1000;
}
}
void loadvideos(){
String video;
vv = new Movie[numfiles];
for (int i=0; i<numfiles; i++){
video= files[int(random(numfiles))];
vv[i] = new Movie(this, video);
println ("Loading ", video);
}
}
class VideoM {
Movie m;
String video;
int x;
int y;
int w;
int h;
int alpha;
int alphai;
int fadeout=0;
VideoM() {
genera();
println(numfiles);
m = vv[int(random(numfiles)) ];
m.loop();
// m.volume(random(0.4,0.6));
// m.speed(random(0.6,1.0));
m.jump(random(m.duration()));
//m.play();
}
void genera(){
x=int(random(50, width/2+width/4));
y=int(random(50, height/2+height/4));
w=int(random(280,820));
h=int(w/1.88);
alpha=int(random(100,255));
alphai=0;
}
void display(){
tint(255, alphai);
if (fadeout==0) {
alphai++; if (alphai>alpha) alphai=alpha;
} else { alphai--; if (alphai<0) {alphai=0;fadeout=0;this.newvid();}
}
if (frameCount > 1) { image(m, x, y, w, h); }
}
void cambiavid(){
fadeout=1;
}
void newvid() {
m=null;
int j=int(random(numfiles));
println("cambio: ", j);
m = vv[j];
m.loop();
genera();
m.jump(random(m.duration()));
println(Thread.currentThread());
}
}
void newset(){
for(int i = 0;i < numVideos;i++){
println(i);
v[i].newvid();
}
}
void newvideo(){
int i = int(random(numVideos));
//v[i].nuevovid(this);
v[i].cambiavid();
}
void movieEvent(Movie m) {
m.read();
}
boolean bStop,bColor=true;
boolean bSave=false,bVidO=false;
void keyPressed()
{
int k = keyCode;
// reset all videos
if (key == 'n' || key == 'N') {
newset();
}
}
// load files in data
String[] files(){
// The data path of the folder to look in (write your own)
java.io.File folder = new java.io.File(dataPath(""));
// let's set a filter (which returns true if file's extension is .jpg)
java.io.FilenameFilter pngFilter = new java.io.FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".mp4");
}
};
// list all the folders inside the main directory
String[] listFolders = folder.list(new java.io.FilenameFilter() {
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
// list the files in the data folder, passing the filter as parameter
String[] filenames = folder.list(pngFilter);
return(filenames);
}
full new version with load and save:
see comments below:
Chrisir ;-)
// Escape is de-activated.
// using selectInput and selectOutput here.
// using also setting path dataPath() and file ending "json".
// fileNameForScreen shows the current file name throughout.
// Uses a JSONArray within a JSONObject.
JSONObject json; // WITHIN this object is an array named animals, see json.setJSONArray("animals", values);
// fileNameForScreen shows the current file name throughout
String fileNameForScreen = "Not a file";
void setup() {
size(660, 660);
background(110);
json = new JSONObject();
// TWO possible test arrays
String[] species = { "Capra hircus", "Panthera pardus", "Equus zebra" };
String[] names = { "Goat", "Leopard", "Zebra" };
// String[] species = { "Cw", "Pp", "Ez" };
// String[] names = { "G", "Leo", "Z" };
//
// build values (JSONArray)
JSONArray values = new JSONArray();
for (int i = 0; i < species.length; i++) {
JSONObject animal = new JSONObject();
animal.setInt("id", i);
animal.setString("species", species[i]);
animal.setString("name", names[i]);
values.setJSONObject(i, animal);
}//for
// add values (JSONArray) to json
// comment this out to generate an error
json.setJSONArray("animals", values);
// generate another error for testing outputJSONArray:
//json = null;
}
void draw() {
background(110);
// show Menu
noFill();
stroke(0);
rect(width-49, 27,
45, 80-27);
fill(0);
text("Load\n\n" + "Save",
width-44, 44);
// show file name
fill(255); // white
text(fileNameForScreen,
min(width-44, width - textWidth(fileNameForScreen) - 11), 15);
// show array
outputJSONArray(json, "animals");
}
// --------------------------------------------------------------------------
void keyPressed() {
// De-activate Escape key
if (key==ESC) {
key=0; // kill Escape
}
}
void mousePressed() {
// println (mouseY);
// right screen border?
if (mouseX>width-50) {
checkMouseOnMenu();
}
}
void checkMouseOnMenu() {
// using selectInput and selectOutput here.
// also setting path and file ending json.
if (mouseY>20&&mouseY<47) {
//Load
String fileString = dataPath("") + "\\" +"*.json" ;
println(fileString);
File toLoad = new File( fileString ) ;
selectInput("Load a file:", "fileSelectedForLoad", toLoad);
} else if (mouseY>48&&mouseY<77) {
//Save
String fileString = dataPath("") + "\\*.json" ;
println(fileString);
File toSave = new File( fileString ) ;
selectOutput("Save to a file:", "fileSelectedForSave", toSave);
} else {
// ignore
}
}
// ---------------------------------------------------------------------------------
void fileSelectedForLoad(File selection) {
File loading;
loading = selection;
if (selection == null) {
println("Window was closed or the user hit cancel.");
} else {
println("User loaded " + selection.getAbsolutePath());
if (loading != null) {
json = loadJSONObject(loading.getAbsolutePath());
fileNameForScreen=loading.getName();//https://docs.oracle.com/javase/7/docs/api/java/io/File.html
}
}//else
//
}
void fileSelectedForSave(File selection) {
File saving;
saving = selection;
if (selection == null) {
println("Window was closed or the user hit cancel.");
} else {
String saveString = saving.getAbsolutePath();
saveString=saveString.trim();
// ending json ok?
if (saveString.indexOf(".json") < 0) {
saveString+=".json"; // very rough approach...
saving = new File(saveString);
}
println("User saved to " + selection.getAbsolutePath());
if (saving != null) {
saveJSONObject(json, saving.getAbsolutePath());
fileNameForScreen=saving.getName();//https://docs.oracle.com/javase/7/docs/api/java/io/File.html
}
}//else
//
}
// ---------------------------------------------------------------------------------
void outputJSONArray(JSONObject json, String nameOfJSONArray) {
// output of an JSONArray named "nameOfJSONArray" in an an JSONObject json.
// The function is not generic since column names "species" etc. must be correct as below.
// error check I.
if (json==null) {
fill(255, 33, 0); // red
text( "No json object", 30, 30+2);
return;
}//if
JSONArray valuesLoaded = json.getJSONArray(nameOfJSONArray);
// error check II.
if (valuesLoaded==null) {
String error = "No json array named "
+ nameOfJSONArray
+ " in json object.";
fill(255, 33, 0); // red
text(error, 30, 30+2);
return;
}//if
fill(40, 255, 17); // black
for (int i = 0; i < valuesLoaded.size(); i++) {
JSONObject animal = valuesLoaded.getJSONObject(i);
int id = animal.getInt("id");
String species = animal.getString("species");
String name = animal.getString("name");
// println(id + ", " + species + ", " + name);
text(id + ", " + species + ", " + name, 40, 50+35*i); // small table
}//for
//
}//func
//
Ok, so implementing @koogs changes are not enough, as you get back to the business of empty recorded files. However, that gave me an idea (Thxs @koogs) which I tested and sort of works. I mean, it only works for mp3 files but not for wav files. However, I tried a second idea, and it might work for you although it doesn't seem to have much control over audio when it is being played. That is what I labeled second solution using sampler objects. It works for both mp3 and wav files (tested).
INSTRUCTIONS: In the code, define your file to play. When you run the sketch, press r to begin recording, r again to stop recording. Don't forget to press s to save the file to an audio file which will be located in the data folder.
Kf
//REFERENCE: https:// forum.processing.org/one/topic/how-can-i-detect-sound-with-my-mic-in-my-computer.html
//REFERENCE: https:// forum.processing.org/two/discussion/21842/is-it-possible-to-perform-fft-with-fileplayer-object-minim
/**
* This sketch demonstrates how to use an <code>AudioRecorder</code> to record audio to disk.
* Press 'r' to toggle recording on and off and the press 's' to save to disk.
* The recorded file will be placed in the sketch folder of the sketch.
* <p>
* For more information about Minim and additional features,
* visit <a href="http://code.compartmental.net/minim/" target="_blank" rel="nofollow">http://code.compartmental.net/minim/</a>
*/
import ddf.minim.*;
import ddf.minim.ugens.*;
import ddf.minim.analysis.*;
Minim minim;
FilePlayer player;
AudioOutput out;
AudioRecorder recorder;
void setup()
{
size(512, 200, P3D);
textFont(createFont("Arial", 12));
minim = new Minim(this);
player = new FilePlayer(minim.loadFileStream("energeticDJ.mp3"));
// IT DOESN'T WORK FOR WAV files ====> player = new FilePlayer(minim.loadFileStream("fair1939.wav"));
out = minim.getLineOut();
TickRate rateControl = new TickRate(1.f);
player.patch(rateControl).patch(out);
recorder = minim.createRecorder(out, dataPath("myrecording.wav"),true);
player.loop(0);
}
void draw()
{
background(0);
stroke(255);
// draw a line to show where in the song playback is currently located
float posx = map(player.position(), 0, player.length(), 0, width);
stroke(0, 200, 0);
line(posx, 0, posx, height);
if ( recorder.isRecording() )
{
text("Currently recording...", 5, 15);
} else
{
text("Not recording.", 5, 15);
}
}
void keyReleased()
{
if ( key == 'r' )
{
// to indicate that you want to start or stop capturing audio data, you must call
// beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
// as many times as you like, the audio data will be appended to the end of the buffer
// (in the case of buffered recording) or to the end of the file (in the case of streamed recording).
if ( recorder.isRecording() )
{
recorder.endRecord();
} else
{
recorder.beginRecord();
}
}
if ( key == 's' )
{
// we've filled the file out buffer,
// now write it to the file we specified in createRecorder
// in the case of buffered recording, if the buffer is large,
// this will appear to freeze the sketch for sometime
// in the case of streamed recording,
// it will not freeze as the data is already in the file and all that is being done
// is closing the file.
// the method returns the recorded audio as an AudioRecording,
// see the example AudioRecorder >> RecordAndPlayback for more about that
recorder.save();
println("Done saving.");
}
}
//REFERENCE: https:// forum.processing.org/one/topic/how-can-i-detect-sound-with-my-mic-in-my-computer.html
//REFERENCE: https:// forum.processing.org/two/discussion/21842/is-it-possible-to-perform-fft-with-fileplayer-object-minim
//REFERENCE: https:// forum.processing.org/two/discussion/21953/why-can-i-only-load-four-audio-files-in-minum
/**
* This sketch demonstrates how to use an <code>AudioRecorder</code> to record audio to disk.
* Press 'r' to toggle recording on and off and the press 's' to save to disk.
* The recorded file will be placed in the sketch folder of the sketch.
* <p>
* For more information about Minim and additional features,
* visit <a href="http://code.compartmental.net/minim/" target="_blank" rel="nofollow">http://code.compartmental.net/minim/</a>
*/
import ddf.minim.*;
import ddf.minim.ugens.*;
import ddf.minim.analysis.*;
Minim minim;
AudioRecorder recorder;
AudioOutput out;
Sampler note;
void setup()
{
size(512, 200, P3D);
textFont(createFont("Arial", 12));
minim = new Minim(this);
out = minim.getLineOut();
note = new Sampler( "energeticDJ.mp3", 4, minim );
//note = new Sampler( "fair1939.wav", 4, minim );
note.patch( out );
recorder = minim.createRecorder(out, dataPath("myrecording.wav"), true);
note.trigger();
}
void draw()
{
background(0);
stroke(255);
if ( recorder.isRecording() )
{
text("Currently recording...", 5, 15);
} else
{
text("Not recording.", 5, 15);
}
}
void keyReleased()
{
if ( key == 'r' )
{
// to indicate that you want to start or stop capturing audio data, you must call
// beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
// as many times as you like, the audio data will be appended to the end of the buffer
// (in the case of buffered recording) or to the end of the file (in the case of streamed recording).
if ( recorder.isRecording() )
{
recorder.endRecord();
} else
{
recorder.beginRecord();
}
}
if ( key == 's' )
{
// we've filled the file out buffer,
// now write it to the file we specified in createRecorder
// in the case of buffered recording, if the buffer is large,
// this will appear to freeze the sketch for sometime
// in the case of streamed recording,
// it will not freeze as the data is already in the file and all that is being done
// is closing the file.
// the method returns the recorded audio as an AudioRecording,
// see the example AudioRecorder >> RecordAndPlayback for more about that
recorder.save();
println("Done saving.");
}
}
Keyword: kf_keyword minim sound recording from wav mp3 files
Tested with both wav and mp3. Data should be placed in data folder.
Kf
//REFERENCE: https:// forum.processing.org/one/topic/how-can-i-detect-sound-with-my-mic-in-my-computer.html
/**
* This sketch demonstrates how to use an <code>AudioRecorder</code> to record audio to disk.
* Press 'r' to toggle recording on and off and the press 's' to save to disk.
* The recorded file will be placed in the sketch folder of the sketch.
* <p>
* For more information about Minim and additional features,
* visit http://code.compartmental.net/minim/
*/
import ddf.minim.*;
import ddf.minim.ugens.*;
Minim minim;
AudioPlayer player;
AudioInput in;
AudioRecorder recorder;
void setup()
{
size(512, 200, P3D);
minim = new Minim(this);
//player = minim.loadFile("energeticDJ.mp3");
player = minim.loadFile("fair1939.wav");
delay(800); //Needed (?)
player.play();
in = minim.getLineIn(Minim.STEREO, 512);
recorder = minim.createRecorder(in, dataPath("myrecording.wav"));
textFont(createFont("Arial", 12));
}
void draw()
{
background(0);
stroke(255);
for(int i = 0; i < player.bufferSize() - 1; i++)
{
float x1 = map( i, 0, player.bufferSize(), 0, width );
float x2 = map( i+1, 0, player.bufferSize(), 0, width );
line( x1, 50 + player.left.get(i)*50, x2, 50 + player.left.get(i+1)*50 );
line( x1, 150 + player.right.get(i)*50, x2, 150 + player.right.get(i+1)*50 );
}
// draw a line to show where in the song playback is currently located
float posx = map(player.position(), 0, player.length(), 0, width);
stroke(0,200,0);
line(posx, 0, posx, height);
if ( recorder.isRecording() )
{
text("Currently recording...", 5, 15);
}
else
{
text("Not recording.", 5, 15);
}
}
void keyReleased()
{
if ( key == 'r' )
{
// to indicate that you want to start or stop capturing audio data, you must call
// beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
// as many times as you like, the audio data will be appended to the end of the buffer
// (in the case of buffered recording) or to the end of the file (in the case of streamed recording).
if ( recorder.isRecording() )
{
recorder.endRecord();
}
else
{
recorder.beginRecord();
}
}
if ( key == 's' )
{
// we've filled the file out buffer,
// now write it to the file we specified in createRecorder
// in the case of buffered recording, if the buffer is large,
// this will appear to freeze the sketch for sometime
// in the case of streamed recording,
// it will not freeze as the data is already in the file and all that is being done
// is closing the file.
// the method returns the recorded audio as an AudioRecording,
// see the example AudioRecorder >> RecordAndPlayback for more about that
recorder.save();
println("Done saving.");
}
}
If you drag the jar into your code in the PDE, then you should be able to access that library (Untested). This is how it works in Processing java and I would assume it is similar for Android mode. If you export the pde into AS, you should be able to see where the jar is located... I believe it will be in the libs folder.
One thing: Do you need to open your csv file in draw()
? If not, move it to setup()
.
Regarding the assets, accessing files, dataPath(), etc. check this: https://forum.processing.org/two/discussion/comment/118947/#Comment_118947
Kf
Try this. It works in my machine: Win 10. If you set the display to zero, it takes both screens. If you set it to 1, it loads in one screen. If 2 is selected, it is loaded in the other screen.
Kf
import processing.video.*;
PApplet projector0;
PApplet projector1;
void settings() {
size(300, 300);
}
void setup() {
smooth(4);
noLoop();
stroke(-1);
projector0 = new ProjectorSketch();
projector1 = new ProjectorSketch();
runSketch(new String[] { "--display=1", "--present", "--sketch-path=" + sketchPath(), "Projector" }, projector0);
}
void draw() {
background(150);
}
class ProjectorSketchX extends PApplet {
color bc;
void settings() {
size(600, 400);
}
void setup() {
bc=color(150, 150, 0);
}
void draw() {
background(bc);
}
}
public class ProjectorSketch extends PApplet {
Movie movie;
public void settings() {
//size(displayWidth, displayHeight, JAVA2D);
size(400, 600);
}
public void setup() {
stroke(#FFFF00);
movie = new Movie(this, dataPath("transit.mov"));
movie.loop();
}
public void draw() {
image(movie, 0, 0, width, height);
}
public void movieEvent(Movie m) {
m.read();
}
}
Keyword: kf_keyword mainSketch, runSketch, multiple windows, multiple PApplets, main function
If you follow the instructions as before, you should be able to run the code below
Kf
import java.util.Map;
import java.util.*;
Table wordsTable;
HashMap<String, Integer> hm = new HashMap<String, Integer>();
List<Map.Entry<String, Integer> > sorted;
void setup() {
size(1280, 720);
background(255, 255, 255);
fill(100);
wordsTable = loadTable(dataPath("data.csv"), "header");
for (TableRow row : wordsTable.rows()) {
hm.put(row.getString("word"), row.getInt("count"));
println(row.getString("word"));
}
sorted = MapUtilities.sortByValue(hm);
float textBoxHeight = 0;
for (Map.Entry<String, Integer> me : sorted) {
//println(me.getKey()+" ==== "+me.getValue());
Integer freq = me.getValue();//hm.get(me.getKey());
String s = "";
for (int i=0; i<freq; i++) {
s = s+me.getKey()+"";
}
println(freq, s);
textBoxHeight = 14*ceil(textWidth(s)/300)+textBoxHeight+7;
text(s.toLowerCase(), 30, 30+textBoxHeight, 300, 500);
}
}
void draw(){ }
Curse my curiosity! :))
Take a look at the Beads library (part of the Contributed libraries for Processing). It can change the playback rate and a lot more. Here is the equivalent of your original sketch, but using Beads. I've modified the playback rate to go from -2.0 (rewind at double speed) to +2.0 (fast-forward at double speed).
// Looping Sample using Beads Library
//
// Processing forum post:
// forum.processing.org/two/discussion/comment/123003/
//
// Reference:
// - Beads home page: www.beadsproject.net/
// - Javadocs: www.beadsproject.net/doc/
import beads.*;
import org.jaudiolibs.beads.*;
SamplePlayer player;
AudioContext ac;
Glide glide;
String sampleName = "dream_center_9secs.wav";
void setup() {
size(400, 400);
ac = new AudioContext();
glide = new Glide(ac, 1);
// WARNING: Beads needs the absolute pathname to sample files! (so use dataPath())
Sample sound = SampleManager.sample(dataPath(sampleName));
if (sound == null) println("Failed to load sample!");
player = new SamplePlayer(ac, sound);
player.setLoopType(SamplePlayer.LoopType.LOOP_FORWARDS);
player.setRate(glide);
Gain g = new Gain(ac, 2, 0.2);
g.addInput(player);
ac.out.addInput(g);
ac.start();
}
void draw() {
}
void mouseMoved() {
// Scale playback rate to be from -2.0 to +2.0
float value = ((float)mouseX - (width / 2)) / (width / 4);
println(value);
// Set playback rate (it's a multiplier),
// 0.0 = pause, 1.0 = normal rate, -1.0 = rewind.
glide.setValue(value);
}
Inspired by Daniel Shiffman "Coding Challenge # 40: 3" https://youtube.com/watch?v=RPMYV-eb6lII made this code to calculate the TF-IDF algorithm. The TF is normalized to avoid biases towards long texts. The words are ordered by their IDF. I'm thinking about how to present the results in a nice way. Ideas are welcome. You can find the complete file with the texts in GitHub: https://github.com/Rayle26/TF-IDF
import java.util.*;
import java.io.*;
Words[] wordData;
File[] files;
Links[] enlace;
String sourceFile = "texts/"; //directory of texts
String[] erase;
String[] nums = {"1","2","3","4","5","6","7","8","9","0"}; // to remove digits from the texts
String[] theWord;
String[] allTheWords;
String[][] textWords;
int[] times;
String[] fileName;
int numFiles;
int textoSelec = 0;
String[][] textWordsPerTxt;
int[][] timesPerTxt;
int[] resultTable;
int[] resultTableTextVal;
PFont font;
int sizeOfText = 12;
void setup() {
size(500, 700);
font = createFont("SourceCodePro-Regular.ttf", sizeOfText);
erase = loadStrings("stopwords-en.txt");
String path = dataPath(sourceFile);
files = listFiles(path);
numFiles = files.length;
String[][] texto = new String[numFiles][0];
allTheWords = new String[numFiles];
textWords = new String[numFiles][0];
IntDict totalDict = new IntDict();
IntDict[] dictionary = new IntDict[numFiles];
textWordsPerTxt = new String[numFiles][0];
timesPerTxt = new int[numFiles][0];
//******loads texts from the directory*****//
for (int i = 0; i <numFiles; i ++) {
texto[i]= loadStrings(sourceFile + files[i].getName());
allTheWords[i] = join(texto[i], " ").toLowerCase();
}
//******removes digits*****//
for (int i = 0; i <nums.length; i ++) {
for(int j = 0; j <allTheWords.length; j ++) {
allTheWords[j] = allTheWords[j].replaceAll(nums[i], "");
}
}
for(int i = 0; i < numFiles; i ++) {
textWords[i] = splitTokens(allTheWords[i], " -,.:;¿?¡!/_\"");
}
//******counts words******//
for (int i = 0; i <numFiles; i ++) {
dictionary[i] = new IntDict();
for(int j = 0; j <textWords[i].length; j ++) {
dictionary[i].increment(textWords[i][j]);
}
}
//******counts words in all the texts******//
for (int i = 0; i <numFiles; i ++) {
for(int j = 0; j <textWords[i].length; j ++) {
totalDict.increment(textWords[i][j]); //da el total de una palabra en todos los textos
}
}
//******removes junk words******//
for(int i = 0; i <erase.length; i ++) {
if(totalDict.hasKey(erase[i]) == true)
totalDict.remove(erase[i]);
for(int j = 0; j < numFiles; j ++) {
if(dictionary[j].hasKey(erase[i]) == true)
dictionary[j].remove(erase[i]);
dictionary[j].sortValuesReverse();
}
}
theWord = totalDict.keyArray();
times = totalDict.valueArray();
for(int i = 0; i <numFiles; i ++) {
textWordsPerTxt[i] = dictionary[i].keyArray();
timesPerTxt[i] = dictionary[i].valueArray();
}
//******document frequency******//
resultTable = new int [theWord.length];
for(int j = 0; j <allTheWords.length; j ++) {
for(int i = 0; i <theWord.length; i ++) {
if(allTheWords[j].contains(theWord[i]) == true)
resultTable[i] = resultTable[i] + 1;
}
}
//******selects only .txt files******//
File Directorio = new File(path);
FilenameFilter ff = new FilenameFilter() {
public boolean accept(File Directorio, String name) {
return name.endsWith(".txt");
}
};
fileName = Directorio.list(ff);
//******creates the links to texts******//
enlace = new Links[numFiles];
for (int i = 0; i < fileName.length; i ++) {
enlace[i] = new Links(60, 68+(sizeOfText*i), textWidth(fileName[i]), sizeOfText, i);
}
}
void draw() {
background(255);
fill(0);
textFont(font);
//*****counts the texts where word appears******//
resultTableTextVal = new int [textWordsPerTxt[textoSelec].length];
for(int i = 0; i <allTheWords.length; i ++) {
for (int j = 0; j < textWordsPerTxt[textoSelec].length; j ++) {
if(allTheWords[i].contains(textWordsPerTxt[textoSelec][0]) == true)
resultTableTextVal[j] = resultTableTextVal[j] + 1;
}
}
//******the core of the code: creates an object (word) with TF and IDF******//
int index = 0;
float idf = 0;
wordData = new Words[textWordsPerTxt[textoSelec].length];
for(int i = 0; i< textWordsPerTxt[textoSelec].length; i ++) {
idf = (float(timesPerTxt[textoSelec][i])/timesPerTxt[textoSelec][0])*log(numFiles/resultTableTextVal[i]); //algoritmo para calcular IDF
wordData[index++] = new Words(textWordsPerTxt[textoSelec][i],timesPerTxt[textoSelec][i],idf);
}
//******sorts objects in ascending order******//
//java.util.Arrays.sort(wordData);
//******sorts objects in descending order******//
Words.isDescent = true;
java.util.Arrays.sort(wordData);
//******shows the list of texts******//
text("Click to select:", 60, 60);
for (int i = 0; i < fileName.length; i ++) {
enlace[i].clickableArea();
String nombreArchivo = fileName[i].replaceFirst("\\.txt", "");
pushMatrix();
translate(60, 80);
text("- " + nombreArchivo, 0, sizeOfText*i);
popMatrix();
}
//******shows the title of text******//
pushMatrix();
translate(200, 20);
textAlign(LEFT);
String titulo = fileName[textoSelec].replaceFirst("\\.txt", "");
text(titulo, 0, 0);
text("Words: " + textWords[textoSelec].length,0, 20);
popMatrix();
//******shows TF-IDF******//
for(int i = 0; i<wordData.length; i ++ ) {
pushMatrix();
translate(200, 60);
textAlign(LEFT);
text(wordData[i].toString(), 0, sizeOfText*i);
popMatrix();
}
noLoop();
}
void mousePressed() {
for (int i = 0; i <numFiles; i ++) {
if(enlace[i].isHovering){
textoSelec = enlace[i].textSelector();
}
}
redraw();
}
void mouseMoved() {
for (int i = 0; i <numFiles; i ++) {
enlace[i].isInside();
}
redraw();
}
class Links {
boolean isHovering;
float textWidth;
int textHeight;
int xpos, ypos;
int textFile;
Links(int xpos_, int ypos_, float textWidth_, int textHeight_, int textFile_) {
textWidth = textWidth_;
textHeight = textHeight_;
xpos = xpos_;
ypos = ypos_;
textFile = textFile_;
}
int textSelector() {
return textFile;
}
void clickableArea() {
noFill();
noStroke();
rect(xpos, ypos, textWidth, textHeight);
}
boolean isInside() {
return isHovering = mouseX > xpos & mouseX < (xpos+textWidth) & mouseY > ypos & mouseY < (ypos + textHeight);
}
}
static class Words implements Comparable<Words> {
static boolean isDescent;
String whichFile;
String word;
Integer frequency;
float inversFreq;
Words(String word_, Integer frequency_, float inversFreq_) {
word = word_;
frequency = frequency_;
inversFreq = inversFreq_;
}
@ Override int compareTo(Words c) {
return Float.compare(inversFreq, c.inversFreq) * (isDescent? -1 : 1);
}
@ Override String toString() {
return word + " (TF: " + frequency + ", " + "IDF: " + inversFreq + ")";
}
}
And this is the outcome:
name,age
john,34
bill,66
"""
Add New Column to Table (v1.1.3)
GoToLoop (2018-Apr-17)
Forum.Processing.org/two/discussion/27767/
can-i-use-f-open-text-w-with-processing#Item_18
"""
from processing.data import Table
def setup():
table = loadTable('original.csv', 'header')
table.columnTypes = [Table.STRING, Table.INT]
printTable(table)
print
addTableIntCol(table, 'car', 2015, 2018)
printTable(table)
saveTable(table, this.dataPath('modified.csv'))
exit()
def printTable(t, IDX='[%d] - ', COL='%s: %s\t'):
for i, tr in enumerate(t.rows()):
PApplet.print(IDX % i)
for col in t.columnTitles:
PApplet.print(COL % (col, tr.getString(col)))
print
def addTableIntCol(t, col, *items):
t.addColumn(col, Table.INT)
setTableIntCol(t, col, *items)
def setTableIntCol(t, col, *items):
it = iter(items)
for tr in t.rows():
i = next(it, it)
if i is it: return
tr.setInt(col, i)
P.S.: When using Processing's save functions, such as saveStrings(), it is highly recommended to call the undocumented dataPath() passing the String filename: L-)
saveStrings( this.dataPath('text.txt'), stringArray )
This way, the file is saved inside sketch's subfolder "data/" instead of its sketchPath's root. :-bd
This is a demonstration managing multiple images, version 1.
Kf
//Multiple-image management using a ring container of defined size n and re-fill triggered by
//image size limit available.
//REFERENCE: https://forum.processing.org/two/discussion/comment/119781/#Comment_119781
//By KF @ 31-Mar-2018
//Suggested improvements:
// Optimization between size, re-fill trigger values which is machine-dependent.
// Rewrite re-fill operation so to use a separate thread
String basedir = "C:\\Users\\C\\Downloads\\data";
String fileext = ".jpg";
int filesInMEM=10;
ImageRingContainer imageManager;
PImage img=null;
boolean switchImages=true; //Enables/disables image increment operation
int lastTime=0; //For time profiling
void setup() {
size(600, 400);
lastTime=millis();
imageManager=new ImageRingContainer(filesInMEM, basedir, fileext);
img=imageManager.get();
}
void draw() {
background(0);
if (img!=null)
image(img, 0, 0);
if (switchImages && frameCount%30==0)
img=imageManager.get();
}
void keyPressed() {
switch(key) {
case ' ':
println("Automatic Image Dispaly: "+( (switchImages=!switchImages)==true ?"Enabled":"Disabled"));
break;
case 'f':
imageManager.printFilenames();
break;
default:
break;
};
}
/**
* This class loads a defined number of images on the fly.
* You provide a folder with a series of iamges to load.
* The program stores the available file names to load.
* The core contains a ring structure where n number of images
* are loaded. Images access are based on a head/tail indices.
* The head keep track where the next image will be extracted.
* The tail keeps track where the next set of images will be
* loaded.
* When the available number of images is less than the minimum
* specified size, the code triggers a refill operation where a
* new set of images are loaded on the tail of the ring.
* If the refill operation exhausts all the available images to
* show, the code will start reusing the images again from the
* initial list.
*/
class ImageRingContainer {
int n; //size of ring buffer
int min_available_limit; //Min number of available images. Otherwise trigger image loading
String path; //Location of images
String extFilter;
String[] filenames; //Current list of image filenames available
ArrayList<PImage> imgCon; //Current iamges loaded
//RING type FIFO
//Images are inserted from the back (at tail) and extracted on the front (at the head)
int headIdx; //Position where an img is poped
int tailIdx; //Position where an image is push
int cIdx; //Current index on filename's array
int verbosity;
ImageRingContainer(int size, String basePath, String ext) {
n=size;
min_available_limit=n/3;
cIdx=0;
headIdx=0;
tailIdx=0;
path=basePath;
extFilter=ext;
verbosity=1;
if (!path.endsWith("\\"))
path+="\\";
imgCon = new ArrayList<PImage>(n);
for (int i = 0; i < n; i++)
imgCon.add(null);
loadFileNames();
upLoadImages(n);
}
int getActiveSize() {
if (tailIdx>headIdx)
return tailIdx-headIdx;
else
return n-headIdx+tailIdx;
}
void loadFileNames() {
java.io.File folder = new java.io.File(dataPath(basedir));
filenames = folder.list(extfilter);
}
synchronized void upLoadImages(int loadN) {
//Load to a maximum of ring size
if (loadN>n) {
println("WARNING: Attempt to load more images (" + loadN + ") than allowable size: " + n);
loadN=n;
}
//If we consummed all the available filenames, then start from the beginning
if (cIdx==filenames.length) {
cIdx=0;
}
//Check if we have enough images to load
if (cIdx+loadN>filenames.length) {
loadN=filenames.length-cIdx;
}
//
for (int i = 0; i < loadN; i++) {
tailIdx=cIdx%n;
PImage ci = loadImage(path+filenames[cIdx++]);
ci.resize(0, height);
imgCon.set(tailIdx, ci);
}
}
synchronized PImage get() {
if (headIdx==tailIdx) {
println("WARNING: Recycling image container list: Head caught up or passed tail");
}
if (getActiveSize()<min_available_limit)
upLoadImages(min_available_limit);
if (verbosity>0) {
println("cidx: "+cIdx+" head@"+headIdx+" tail@"+tailIdx+" delta Time: "+(millis()-lastTime));
}
lastTime=millis();
PImage ci = imgCon.get(headIdx);
headIdx = (headIdx+1)%n;
return ci;
}
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(extFilter);
}
};
void printFilenames() {
for (int i = 0; i < filenames.length; i++) {
println(nf(i, 2, 0)+" => "+path+filenames[i]);
}
}
}
//cidx: 10 head@0 tail@9 delta Time: 467
//cidx: 10 head@1 tail@9 delta Time: 485
//cidx: 10 head@2 tail@9 delta Time: 501
//cidx: 10 head@3 tail@9 delta Time: 498
//cidx: 10 head@4 tail@9 delta Time: 501
//cidx: 15 head@5 tail@4 delta Time: 713
//cidx: 15 head@6 tail@4 delta Time: 484
//cidx: 15 head@7 tail@4 delta Time: 500
//cidx: 15 head@8 tail@4 delta Time: 500
//cidx: 15 head@9 tail@4 delta Time: 499
//cidx: 20 head@0 tail@9 delta Time: 753
//cidx: 20 head@1 tail@9 delta Time: 486
//cidx: 20 head@2 tail@9 delta Time: 499
//cidx: 20 head@3 tail@9 delta Time: 501
//cidx: 20 head@4 tail@9 delta Time: 498
//cidx: 25 head@5 tail@4 delta Time: 975
//cidx: 25 head@6 tail@4 delta Time: 485
//cidx: 25 head@7 tail@4 delta Time: 501
//cidx: 25 head@8 tail@4 delta Time: 500
//cidx: 25 head@9 tail@4 delta Time: 501
//cidx: 30 head@0 tail@9 delta Time: 736
//cidx: 30 head@1 tail@9 delta Time: 486
//cidx: 30 head@2 tail@9 delta Time: 501
//cidx: 30 head@3 tail@9 delta Time: 498
//cidx: 30 head@4 tail@9 delta Time: 501
//cidx: 35 head@5 tail@4 delta Time: 1036
//cidx: 35 head@6 tail@4 delta Time: 485
//cidx: 35 head@7 tail@4 delta Time: 500
//cidx: 35 head@8 tail@4 delta Time: 500
//cidx: 35 head@9 tail@4 delta Time: 499
//cidx: 40 head@0 tail@9 delta Time: 803
//cidx: 40 head@1 tail@9 delta Time: 485
//cidx: 40 head@2 tail@9 delta Time: 498
//cidx: 40 head@3 tail@9 delta Time: 501
//cidx: 40 head@4 tail@9 delta Time: 498
//cidx: 45 head@5 tail@4 delta Time: 802
//cidx: 45 head@6 tail@4 delta Time: 485
//cidx: 45 head@7 tail@4 delta Time: 500
//cidx: 45 head@8 tail@4 delta Time: 499
//cidx: 45 head@9 tail@4 delta Time: 499
//cidx: 50 head@0 tail@9 delta Time: 947
//cidx: 50 head@1 tail@9 delta Time: 485
//cidx: 50 head@2 tail@9 delta Time: 500
//cidx: 50 head@3 tail@9 delta Time: 500
//cidx: 50 head@4 tail@9 delta Time: 501
//cidx: 55 head@5 tail@4 delta Time: 623
//cidx: 55 head@6 tail@4 delta Time: 488
//cidx: 55 head@7 tail@4 delta Time: 500
//cidx: 55 head@8 tail@4 delta Time: 499
//cidx: 55 head@9 tail@4 delta Time: 502
//cidx: 60 head@0 tail@9 delta Time: 650
//cidx: 60 head@1 tail@9 delta Time: 485
//cidx: 60 head@2 tail@9 delta Time: 500
//cidx: 60 head@3 tail@9 delta Time: 502
//cidx: 60 head@4 tail@9 delta Time: 498
//cidx: 61 head@5 tail@0 delta Time: 524
//cidx: 5 head@6 tail@4 delta Time: 668
//cidx: 5 head@7 tail@4 delta Time: 485
//cidx: 5 head@8 tail@4 delta Time: 501
//cidx: 5 head@9 tail@4 delta Time: 499
//cidx: 10 head@0 tail@9 delta Time: 731
//cidx: 10 head@1 tail@9 delta Time: 486
//cidx: 10 head@2 tail@9 delta Time: 499
//cidx: 10 head@3 tail@9 delta Time: 500
//cidx: 10 head@4 tail@9 delta Time: 500
//cidx: 15 head@5 tail@4 delta Time: 676
//cidx: 15 head@6 tail@4 delta Time: 485
//cidx: 15 head@7 tail@4 delta Time: 500
http://www.java-gaming.org/topics/game-loops/24220/view.html
https://forum.processing.org/two/discussion/comment/121981/#Comment_121981
www.programering.com/a/MzN1czNwATQ.html
I have read elsewhere in the forum that a good way to do this is to use an ArrayList (https://forum.processing.org/two/discussion/767/dynamic-image-array), but I am not sure how to create an ArrayList of images that calls up images from a folder. I have checked the processing referencing page (https://processing.org/reference/ArrayList.html), though I don't know how to change from calling a single object like a particle to calling images from a folder.
I have changed the following before setup:
String basedir = "/Users/admin/Desktop/Borderscape_OF/test";
String fileext = ".jpg";
//PImage[] images;
ArrayList<PImage> imgList = new ArrayList<PImage>();
PImage img;
int i;
String[] filenames;
boolean isCycling = true;
boolean glitch = false;
boolean saveimage = false;
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(fileext);
}
};
and have added the following to setup:
filenames = folder.list(extfilter);
imgList = new ArrayList<PImage>();
for (int h = 0; h < 10; h++) {
imgList.add(new PImage());
but I don't know how to get it to call the images from the folder.
I am trying to optimize a sketch where instead of loading 200 images to an array, I am loading only 10 at a time that are cycled through, but keeps updating throughout the sketch so it goes through all the images. I have read elsewhere in the forum that a good way to do this is to use an ArrayList, but I am not sure how to create an ArrayList of images that calls up images from a folder.
I got as far as this:
String basedir = "/Users/admin/Desktop/Borderscape_OF/test";
String fileext = ".jpg";
ArrayList<PImage> imgList = new ArrayList<PImage>();
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(fileext);
}
};
void setup() {
fullScreen();
frameRate(7);
background(0);
filenames = folder.list(extfilter);
imgList = new ArrayList<PImage>();
for (int h = 0; h < 10; h++) {
imgList.add(new PImage());
}
}
But now I am stuck.
When I tried implementing those changes, it comes up blank with no error message. Here is my code:
String basedir = "/Users/admin/Desktop/Borderscape_OF/clean";
String fileext = ".jpg";
int i = 0;
String[] filenames;
int imgSize = 182;
boolean isCycling = true;
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
//return name.toLowerCase().endsWith(fileext);
return name.endsWith(fileext);
}
};
PImage[] images;
void setup() {
fullScreen();
frameRate(7);
background(0);
filenames = folder.list(extfilter);
images = new PImage[filenames.length];
for (int i = 0; i<filenames.length; i++) {
images [i] = loadImage(basedir+"/"+filenames[i]); // load all in one go here
}
}
void draw() {
keyPressed();
//img = loadImage(basedir+"/"+filenames[i]);
float x = random(0, 255);
tint(255, x);
image(images [i], 0, 0);
if (isCycling) {
i++;
}
if (i + 1 == filenames.length) {
i = 0;
}
}
void keyPressed() {
if (key == 'x') {
basedir = "/Users/admin/Desktop/Borderscape_OF/glitched";
}
if (key == 's') {
basedir = "/Users/admin/Desktop/Borderscape_OF/clean";
}
if (key == ' ') {
isCycling = false;
}
if (key == RETURN || key == ENTER) {
isCycling = true;
}
}
Hello,
I have created a sketch that cycles through images, but when I hit the spacebar, I want it to stop cycling through the images and remain on that particular image until I hit the return key. I don't know how to implement that. Here is my code:
String basedir = "/Users/admin/Desktop/Borderscape_OF/clean";
String fileext = ".jpg";
PImage img;
int i = 0;
String[] filenames;
int imgSize = 182;
java.io.File folder = new java.io.File(dataPath(basedir));
java.io.FilenameFilter extfilter = new java.io.FilenameFilter() {
boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(fileext);
}
};
void setup() {
fullScreen();
frameRate(7);
background(0);
//pull from string
filenames = folder.list(extfilter);
img = loadImage(basedir+"/"+filenames[0]);
surface.setSize(img.width, img.height); // Takes the size of the first image in the folder.
}
void draw() {
keyPressed();
img = loadImage(basedir+"/"+filenames[i]);
float x = random(0, 255);
tint(255, x);
image(img, 0, 0);
i++;
if (i + 1 == filenames.length) {
i = 0;
}
}
void keyPressed() {
if (key == 'x') {
basedir = "/Users/admin/Desktop/Borderscape_OF/glitched";
}
if (key == 's') {
basedir = "/Users/admin/Desktop/Borderscape_OF/clean";
}
}