Loading...
Logo
Processing Forum
hello.

i'm trying to save a .png in a specific location in my computer and the following code shows what i'm doing...

Copy code
  1. PGraphics pg;

  2. void setup () {
  3.   size(600, 600);
  4.   pg = createGraphics(600, 600);
  5. }

  6. void draw() {
  7.   pg.beginDraw();
  8.   pg.fill(0, 255, 0);
  9.   pg.rectMode(CENTER);
  10.   pg.rect(width/2, height/2, 120, 120);
  11.   pg.endDraw();
  12.   image(pg,0, 0);
  13. }

  14. void keyReleased() {
  15.   selectFolder("Select a folder to process:", "folderSelected");
  16. }

  17. void folderSelected(File selection) {
  18.   if (selection == null) {
  19.     println("Window was closed or the user hit cancel.");
  20.   } 
  21.   else {
  22.     String location = selection.getAbsolutePath();
  23.     pg.save(location + "test.png");
  24.       }
  25. }

if i change ' pg.save(location + "test.png");' for this ----> ' pg.save(/Users/myName/Desktop + "test.png");' it works perfectly...

so, is it possible to do specify a location to save my png?

another question... if i run this sketch as a java applet in a website, will it run? what is the best option if want to implement something like this online? i was thinking in using processing.js, but in my original sketch i'm using libraries to create .pdf and also the controlp5 librarie... i've been told that isn't possible to use libraries in processing.js. so i'm not sure what will be the best option for me. any suggestions?

thanks guys.

Replies(10)

Sooo... what is the problem with the code you show?
My guess, which you can confirm with a simple printlln(), is that you need a slash between location and the file name...

And, indeed, you cannot do that (not in a simple way, at least), with PJS.
You can export the sketch to a Java applet with Processing 1.5.1 (or a tool somebody (quarks, I think), created).

Sooo... what is the problem with the code you show?
 
the problem is, despite i'm able to select the saving location of my file, the file isn't saved.


My guess, which you can confirm with a simple printlln(), is that you need a slash between location and the file name...
i didn't got where i'm supposed to put the slash, sorry. something like this:
Copy code
  1. pg.save(location/ + "test.png");                                                                                                             
or this:
Copy code
  1. pg.save(location / "test.png");
it doesn't work... :S
Just tidbit tips! 

I like to save files inside the same folder as a sketch runs. More specifically inside subfolder \data.
For that I use function dataPath():

final String path = dataPath("test.png");
pg.save(path);

Below there are some posts where that is used:

Now, about Java applets, only Processing v1.5.1 has a built-in solution. Although there has 1 hack for P2.
And if you press <CTRL>+E, it generates a subfolder ready to use your code as an applet.

However, Java applets are constantly being the target of hacks where its sandbox is nullified.
And evil code is leaked thru' it and invades its host machine!

Due to it, Oracle's making difficult to run applets w/o a valid certificate. Bad news for developers!  
based on your examples i've tried this...

Copy code

  1. PGraphics pg;

  2. void setup () {
  3.   size(600, 600);
  4.   pg = createGraphics(600, 600);
  5. }

  6. void draw() {
  7.   pg.beginDraw();
  8.   pg.fill(0, 255, 0);
  9.   pg.rectMode(CENTER);
  10.   pg.rect(width/2, height/2, 120, 120);
  11.   pg.endDraw();
  12.   image(pg,0, 0);
  13. }

  14. void keyReleased() {
  15.   selectFolder("Select a folder to process:", "folderSelected");
  16. }

  17. void folderSelected(File selection) {
  18.   if (selection == null) {
  19.     println("Window was closed or the user hit cancel.");
  20.   } 
  21.   else {
  22.     String location = selection.getAbsolutePath("test.png");
  23.     pg.save(location);
  24.       }
  25. }      
but i got this error...

" The method getAbsolutePath() in the type File is not applicable for arguments (String) "


Yes, you have to use
String location = selection.getAbsolutePath() + "/test.png");
instead.
hey guys.

once again i'm trying to use the folderSelected() function but this time in a more complex situation... (at least for me).

because i need to save a high resolution image of my sketch i'm using this example  https://github.com/shengpo/processing_snips/tree/master/aTileSaverSimpleTest

although, my code isn't working... can you take a look and tell me what am I doing wrong?

Sketch (1/2):

Copy code
  1. aTileSaver tiler;  
  2. boolean savingPNG;
  3. String location;

  4. void setup() {  
  5.     size(500, 500, P3D);  
  6.     noStroke();  
  7.     tiler=new aTileSaver(this);
  8. }  

  9. public void draw() {  
  10.     if (tiler==null) return; // Not initialized  

  11.     // call aTileSaver.pre() to prepare frame and setup camera if it exists.  
  12.     tiler.pre();  

  13.     background(0, 50, 0);  
  14.     lights();  

  15.     pushMatrix();
  16.     translate(width/2, height/2);  
  17.     rotateY(PI/4);  
  18.     rotateX(PI/4);  
  19.     scale(8);  
  20.     fill(240, 255, 0, 220);  
  21.     box(10, 50, 10);  
  22.     fill(150, 255, 0, 220);  
  23.     box(50, 10, 10);  
  24.     fill(255, 150, 0, 220);  
  25.     box(10, 10, 50);  
  26.     popMatrix();

  27.     // call aTileSaver.post() to update tiles if tiler is active  
  28.     tiler.post();
  29. }  

  30. // Saves tiled imaged when 't' is pressed  
  31. public void keyPressed() {  
  32.     if (key=='t') tiler.init("Simple"+nf(frameCount, 6), 6);
  33. }  

Class (2/2):

Copy code
  1. class aTileSaver {  
  2.   public boolean isTiling=false, done=true;  
  3.   public boolean doSavePreview=true;  

  4.   PApplet p;  
  5.   float FOV=60; // initial field of view  
  6.   float cameraZ, width, height;  
  7.   int tileNum=10, tileNumSq; // number of tiles  
  8.   int tileImgCnt, tileX, tileY;  
  9.   boolean firstFrame=false, secondFrame=false;  
  10.   String tileFilename, tileFileExt=".tga";  
  11.   //String tileFilename, tileFileExt=".png";  
  12.   PImage tileImg;  
  13.   float perc, percMilestone;  

  14.   String location;
  15.   boolean savingPNG = false;

  16.   // The constructor takes a PApplet reference to your sketch.  
  17.   public aTileSaver(PApplet _p) {  
  18.     p=_p;
  19.   }  

  20.   // If init() is called without specifying number of tiles, getMaxTiles()  
  21.   // will be called to estimate number of tiles according to free memory.  
  22.   public void init(String _filename) {  
  23.     init(_filename, getMaxTiles(p.width));
  24.   }  

  25.   // Initialize using a filename to output to and number of tiles to use.  
  26.   public void init(String _filename, int _num) {  
  27.     tileFilename=_filename;  
  28.     tileNum=_num;  
  29.     tileNumSq=(tileNum*tileNum);  

  30.     width=p.width;  
  31.     height=p.height;  
  32.     cameraZ=(height/2.0f)/p.tan(p.PI*FOV/360.0f);  
  33.     p.println("aTileSaver: "+tileNumSq+" tiles and Resolution: "+(p.width*tileNum)+"x"+(p.height*tileNum));  

  34.     // remove extension from filename  
  35.     if (!new java.io.File(tileFilename).isAbsolute())  
  36.       tileFilename=p.dataPath(tileFilename);  
  37.     tileFilename=noExt(tileFilename);  
  38.     p.createPath(tileFilename);  
  39.       
  40.       //==============================================MY CHANGES===============

  41.     // save preview
  42.     if ( !savingPNG) {
  43.       location = null;
  44.       savingPNG = true;
  45.       selectFolder("Select a folder to process:", "folderSelected");    
  46.     }
  47.   
  48.   if (location != null /*&& doSavePreview*/) {
  49.     savingPNG = false;
  50.     p.g.save(location + "myImage.png");
  51.   }

  52.     //==============================================  

  53.     // set up off-screen buffer for saving tiled images  
  54.     tileImg=new PImage(p.width*tileNum, p.height*tileNum);  

  55.     // start tiling  
  56.     isTiling=true;  
  57.     firstFrame=true;          //for skip first frame after do tiling
  58.     secondFrame=true;     //for skip second frame after do tiling
  59.     tileImgCnt=0;
  60.     tileX = 0;
  61.     tileY = 0;

  62.     done=false;  
  63.     perc=0;  
  64.     percMilestone=0;
  65.   }  

  66.   // set filetype, default is TGA. pass a valid image extension as parameter.  
  67.   public void setSaveType(String extension) {  
  68.     tileFileExt=extension;  
  69.     if (tileFileExt.indexOf(".")==-1) tileFileExt="."+tileFileExt;
  70.   }  

  71.   // pre() handles initialization of each frame.  
  72.   // It should be called in draw() before any drawing occurs.  
  73.   public void pre() {  
  74.     if (!isTiling) return;  
  75.     if (firstFrame) {
  76.       firstFrame=false;
  77.     } 
  78.     else if (secondFrame) {  
  79.       secondFrame=false;
  80.     }  
  81.     setupCamera();
  82.   }  

  83.   // post() handles tile update and image saving.  
  84.   // It should be called at the very end of draw(), after any drawing.  
  85.   public void post() {  
  86.     // If first or second frame, don't update or save.  
  87.     if (firstFrame || secondFrame || (!isTiling)) return;  

  88.     // Get current image from sketch and draw it into buffer  
  89.     p.loadPixels();  
  90.     tileImg.set(tileX*p.width, tileY*p.height, p.g);  

  91.     // Increment tile index  
  92.     tileImgCnt++;  
  93.     perc=100*((float)tileImgCnt/(float)tileNumSq);  
  94.     if (perc-percMilestone> 5 || perc>99) {  
  95.       p.println(p.nf(perc, 3, 2)+"% completed. "+tileImgCnt+"/"+tileNumSq+" images saved.");  
  96.       percMilestone=perc;
  97.     }  

  98.     if (tileImgCnt==tileNumSq) tileFinish();  
  99.     else tileInc();
  100.   }  

  101.   public boolean checkStatus() {  
  102.     return isTiling;
  103.   }  

  104.   // tileFinish() handles saving of the tiled image  
  105.   public void tileFinish() {  
  106.     isTiling=false;  

  107.     restoreCamera();  

  108.     // save large image to TGA  
  109.     tileFilename+="_"+(p.width*tileNum)+"x"+(p.height*tileNum)+tileFileExt;  
  110.     p.println("Save: "+tileFilename.substring(tileFilename.lastIndexOf(java.io.File.separator)+1));  
  111.     tileImg.save(tileFilename);  
  112.     p.println("Done tiling.n");  

  113.     // clear buffer for garbage collection  
  114.     tileImg=null;  
  115.     done=true;
  116.   }  

  117.   // Increment tile coordinates  
  118.   public void tileInc() {  
  119.     if (tileX==tileNum-1) {  
  120.       tileX=0;  
  121.       tileY=(tileY+1)%tileNum;
  122.     } 
  123.     else {  
  124.       tileX++;
  125.     }
  126.   }  

  127.   // set up camera correctly for the current tile
  128.   //caution: camera's coordination system si different from drawing's coordination system
  129.   //              so, must be very care of parameters in camera() and frustum() !!
  130.   public void setupCamera() {  
  131.     //reset to default camera coordination with Y-UP (up-increase), and original poit is at (width/2f, height/2f, 0)
  132.     p.camera(width/2.0f, height/2.0f, cameraZ, width/2.0f, height/2.0f, 0, 0, 1, 0); 

  133.     if (isTiling) {  
  134.       //set to a specific perspective (or clipping volume) with enough near near-plane and enough far far-plane
  135.       //this step is to fix the viewport on each tile
  136.       float mod=1f/10f;  //to make near plane is close to camera(aka eye)
  137.       p.frustum((-width/2f + width*((float)tileX/(float)tileNum))*mod, //left
  138.       (-width/2f + width*((tileX+1)/(float)tileNum))*mod, //right
  139.       (height/2f - height*((tileY+1)/(float)tileNum))*mod, //bottom
  140.       (height/2f - height*((float)tileY/(float)tileNum))*mod, //up
  141.       cameraZ*mod, 10000);                                                //near, far
  142.     }
  143.   }  

  144.   // restore camera once tiling is done  
  145.   public void restoreCamera() {  
  146.     //reset to default camera coordination with Y-UP (up-increase), and original poit is at (width/2f, height/2f, 0)
  147.     p.camera(width/2.0f, height/2.0f, cameraZ, width/2.0f, height/2.0f, 0, 0, 1, 0);  

  148.     //reset to default perspective (or clipping volume) with enough near near-plane and enough far far-plane
  149.     float mod=1f/10f;  //to make near plane is close to camera(aka eye)
  150.     p.frustum(-(width/2)*mod, (width/2)*mod, //left, right
  151.     -(height/2)*mod, (height/2)*mod, //bottom, up
  152.     cameraZ*mod, 10000);                    //near, far
  153.   }  

  154.   // checks free memory and gives a suggestion for maximum tile  
  155.   // resolution. It should work well in most cases, I've been able  
  156.   // to generate 20k x 20k pixel images with 1.5 GB RAM allocated.  
  157.   public int getMaxTiles(int width) {  
  158.     // get an instance of java.lang.Runtime, force garbage collection  
  159.     java.lang.Runtime runtime=java.lang.Runtime.getRuntime();  
  160.     runtime.gc();  

  161.     // calculate free memory for ARGB (4 byte) data, giving some slack  
  162.     // to out of memory crashes.  
  163.     int num=(int)(Math.sqrt((float)(runtime.freeMemory()/4)*0.925f))/width;  
  164.     p.println(((float)runtime.freeMemory()/(1024*1024))+"/"+((float)runtime.totalMemory()/(1024*1024)));  

  165.     // warn if low memory  
  166.     if (num==1) {  
  167.       p.println("Memory is low. Consider increasing memory.");  
  168.       num=2;
  169.     }  

  170.     return num;
  171.   }  

  172.   // strip extension from filename  
  173.   String noExt(String name) {  
  174.     int last=name.lastIndexOf(".");  
  175.     if (last>0)  
  176.       return name.substring(0, last);  

  177.     return name;
  178.   }
  179. }  

  180.        //===========================================MY CHANGES===============

  181. public void folderSelected(File selection) {
  182.   if (selection == null) {
  183.     println("Window was closed or the user hit cancel.");
  184.     location = "";
  185.   } 
  186.   else {
  187.     location = selection.getAbsolutePath();
  188.     println(location);
  189.   }
  190. }   
Hard to analyze such wall of code... It is often useful to do a very simple sketch down to the precise problem, with dummy classes / graphics.

Anyway, from a quick glance, I notice you have a global location variable, and a field of same name inside the class. The folderSelected method sets the global variable, but apparently you check the value of the field, probably still null.
Don't forget, also, that selectFolder returns immediately, before the user gives its choice, so the location is still empty after its call.
Thanks @PhiLho. The issue was related with that.

it was happening that as I pressed 'T' in my keyboard, i was automatically running the code that generates the .png and .tga files. this way the code was reaching the end before i had selected my save location.

now, after the user press the 'T' key he's asked to select the save location. when this location is defined the rest of the code is able to run and to create my files (.png + .tga) in the desirable location.

just one more question. if i save my file like this, everything goes perfect... : 
Copy code
  1. p.g.save(location + "/myPreview.png");
 but if want to give the file name automatically and to do something like this, it won't work...
Copy code
  1. p.g.save( location + tileFilename+"_preview.png");
I've also tried this but without success:
Copy code
  1. p.g.save( location + "/"+tileFilename+"_preview.png");
any hint?

thanks!
The second attempt is better, indeed...
What is the error message?
Do a println() of your expression, to see if it is correct.
i wrote a message to the author of the aTilerSaver.pde-example and he updated his example in way to allow the user to select the save location. pretty awesome!

to anyone who needs it, here is the link again: