Saved image is empty

edited January 2017 in Android Mode

Hi,

I am drawing on a PGraphics and want to save the rendered image to the relevant pictures directory on the external storage. I have set the proper WRITE_EXTERNAL_STORAGE permission. I am using createGraphics() and later save() and everything seems to work fine, but the resulting image is an empty file (0.00 byte).

import android.os.Environment;

try {
  if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
    throw new Exception("External storage is not writable.");
  }

  File directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "draw");
  if (!directory.exists() && !directory.mkdirs()) {
    throw new Exception("Directory could not be created.");
  }

  String filename = directory.getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg";
  canvas.save(filename);

  println("Picture has been saved to: " + filename);
} catch (Exception e) {
  this.showDialog("Error", e.getMessage());
}

This code would print Picture has been saved to: /storage/emulated/0/Pictures/draw/1483309392341.jpg but the resulting image is an empty file.

Did I miss something?

Answers

  • @antiplastik=== ia am quite sure that your code runs as for the path but it creates an empty file (yet you can "find" it if you try listing your directory folder); so in my mind the problem is with your canvas.save(): but i cannot see in your code when this canvas was created ...

  • @akenaton actually this is a simple PGraphics object:

    void setup() {
        fullScreen();
        canvas = createGraphics(width, height);
        canvas.background(255);
        // some more drawing on "canvas" in draw()
    }
    

    I've found this issue that could be related: https://github.com/processing/processing-android/issues/250

    Will dig into the source code...

  • OK, I managed to save the picture by setting the DISABLE_ASYNC_SAVEFRAME hint with:

    canvas.hint(DISABLE_ASYNC_SAVEFRAME);
    canvas.save(filename);
    

    which bypasses the AsyncImageSaver: https://github.com/processing/processing-android/blob/android-255/core/src/processing/core/PGraphics.java#L5709-L5711

    so I guess there is something wrong with the AsyncImageSaver here.

  • Thanks for sharing your solution.

    Kf

  • edited January 2017

    @antiplastik=== ok:that means that there is a problem with save ()+android mode,which seemed to me probable; and your solution works... but for PGraphics object ( though i dont understand why!!!, because it s only (according with .docs) a question of Asynctask or not))

    Now try to save some frame (not pGraphics) and see what happens...

    I have done that and tried a lot of solutions (even native android code):: in the best case i get some Image which has a width, an height, a name... that i can load() and i am happy but it is black!!! can you explain???

    PS: of course, anyway, i can get an image using your workaround but that is ugly PS2 : anywise save() (Without path, only filename) save nothing,, against what .docs are saying...

  • Answer ✓

    @antiplastik===

    ok, i finally got it (i mean not using Graphics, but perhaps it works also with it); it was more simple than i thought: main problem is that the save() method in android does not work as in java. Try the code below, which btw, is a solution for a screen shot.

    PS= a lot of imports are useless, only for testing!

        import android.net.Uri;
        import android.content.Intent;
        import android.graphics.Bitmap;
        import android.widget.FrameLayout;
        import java.io.FileNotFoundException;
        import java.io.FileOutputStream;
        import java.io.ByteArrayOutputStream;
        import android.view.View;
        import android.graphics.Bitmap;
        import android.graphics.Canvas;
        import android.os.Environment;
        import android.app.Activity;
    
        PGraphics pg;
        PImage[] imag;
        File[] listOfFiles;
        String files;
        String [] Resultat;
    
        Canvas canvas;
        FrameLayout fl;
        PApplet pAp;
        boolean charge = false;
    
        public void onStart(){
          super.onStart();
          fl = (FrameLayout)this.getActivity().findViewById(0x1000);
        }
    
        void settings(){
          size(displayWidth, displayHeight);
        }
        void setup(){
          //place une image dans la dsCard; ne pas oublier les permissions dans le manifeste
          orientation(PORTRAIT);
    
        background(255,0,0);
        //pg = createGraphics(400, 800);
    
        }
         void draw(){
           background(255,0,0);
            //pg.beginDraw();
          //pg//.background(102);
          //pg//.stroke(255);
          //pg//.fill(0,255,0);
          //pg//.ellipse(50,50, 100,100);
          ///pg//.endDraw();
    
          if(!charge){
          ///image(pg, 50, 50);
          fill(0,255,0);
          ellipse(100,100,100,100);
    
          }else{
           background(0);
           PImage img = loadImage("essaiencre.jpg");
           image (img, 400,400);
           fill(0,0,255);
           rect(0,0,100,100);
          }
    
    
         }
    
    
    
        void saveImageInit(){
           try
            {
    
                PImage temp= this.get();
                 String nom = "essaiencre.jpg" ;
               temp.save(nom);
    
                verifie();
            } 
    
            catch (Exception e) 
            {
                println("Error while saving file: " + e.getMessage());      
            }
    
    
        }
        public void verifie(){
          String directory = new String(Environment.getExternalStorageDirectory().getAbsolutePath() );
        File folder = new File(directory);
          listOfFiles = folder.listFiles(); 
          Resultat = new String[listOfFiles.length];
    
        imag=new PImage[listOfFiles.length];
    
          for (int i = 0; i < listOfFiles.length; i++) 
          {
    
          if (listOfFiles[i].isFile()) 
          {
          files = listOfFiles[i].getName();
          Resultat[i] = files;
          System.out.println("i=====" + i + "    " + files);
         }
         }
    
    
          charge= true;
    
        }
    
        void mouseReleased(){
          saveImageInit();
          verifie();
    
    
        }
    
  • @antiplastik=== tested:: it also works with pGraphics

  • Indeed converting to PImage with get() does the trick, thanks!

    PGraphics graphics = createGraphics(width, height);
    PImage image = graphics.get();
    image.save(someAbsolutePath);
    
  • @antiplastik=== yes, it works fine; what is strange is that it does not use any path and yet create the file in the external storage (that s why i have added the verifie() method in my code); when i get some more time i shall se what happens if you add some absolute path in save()... Anyway i think that this could be added to the doc for android save() which seems to do nothing (as it s said on the github link you have given)

Sign In or Register to comment.