We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › trouble saving JPG image
Page Index Toggle Pages: 1
trouble saving JPG image (Read 911 times)
trouble saving JPG image
Oct 1st, 2007, 8:01am
 
I am trying to save the current frame to a file, but I cannot use "saveFrame" because I want to be able to control the JPG "Quality".  In the code below it is 50%.

I also want to have access to the JPG-encoded bytes, since I plan to send them over the net to a server. For now, I am saving to a file to check the JPG encoding worked.

With the code below, an image file gets created, but the colours are all wrong.
The problem seems to be the pixel format parameter in:
Code:
new BufferedImage(width, height, 1); 



Does anyone know the proper parameter value for the "ARGB" format used by Processing?

I looked in the Processing source code for the "save" function (saveImageIO, actually), and I can't quite follow it.  Also, ... I don't know how to modify it to encode the image into a byte array, instead of writing it directly to a file.

http://dev.processing.org/source/index.cgi/trunk/processing/core/src/processing/core/PImage.java?view=markup

If there are any Java / JPG gurus out there, I'd appreciate any help you can offer.

Code:

void SaveJpg(String fname) {
 loadPixels();
     
 try {
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
   BufferedImage img = new BufferedImage(width, height, 1);
   img = (BufferedImage) createImage(width, height);

   /* for (j = 0; j < height; ++j) {
     k = j*width;
     for (i = 0; i < width; ++i) {
       img.setRGB(i,j, pixels[k+i]);
     }
   }
   */
   img.setRGB(0,0,width,height,pixels,0,width);
   encoder = JPEGCodec.createJPEGEncoder(out);
   JPEGEncodeParam p = encoder.getDefaultJPEGEncodeParam(img);
   // set JPEG quality to 50% with baseline optimization
   p.setQuality(0.50,true);
   encoder.setJPEGEncodeParam(p);
   encoder.encode(img);
   byte [] a = out.toByteArray();
   saveBytes(fname,a);
 }
 catch(FileNotFoundException e){
   System.out.println(e);
 }
 catch(IOException ioe){
   System.out.println(ioe);
 }
}


thanks,
 djones
Re: trouble saving JPG image -- 2
Reply #1 - Oct 1st, 2007, 1:22pm
 
the correct image format is:

image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Re: trouble saving JPG image
Reply #2 - Oct 3rd, 2007, 5:20am
 
Thanks Ben.

I added that line, but the file still looks wonky.  It almost looks like a photographic negative, but inverting it doesn't make it look right either.

I saved an example image online:  http://dxjones.com/processing/save.jpg

I can't figure out what I am doing wrong.

Any suggestions would be appreciated.

-- djones
Re: trouble saving JPG image
Reply #3 - Oct 3rd, 2007, 1:00pm
 
check these:

http://www.processinghacks.com/hacks/saveasjpg
http://www.processinghacks.com/hacks/savetoweb

F
Re: trouble saving JPG image
Reply #4 - Oct 3rd, 2007, 2:07pm
 
bizarre, this image seems to be in CMYK format. i'm guessing that it's trying to write 4 channels of data, which JPEG decoders interpret as CMYK (since JPEG has no alpha channel), thus the inverted colors.

but as fjen notes, the place to go is the hacks site, which has a working hack.
Re: trouble saving JPG image
Reply #5 - Oct 4th, 2007, 8:31pm
 
I tried the "saveasjpg" example verbatim (i.e., no changes at all) and it gave be the same messed up file (http://www.dxjones.com/save.jpg).  On the same computer "saveFrame" works correctly.

I am running Processing 0125, Mac OSX 10.4.10, 2.5 GHz G5.

My goal is to use the "savetoweb" example to save images from an applet.  Unfortunately, "saveFrame" is not available to an applet, since it can't write to disk.

-- djones

fjen wrote on Oct 3rd, 2007, 1:00pm:
check these:

http://www.processinghacks.com/hacks/saveasjpg

http://www.processinghacks.com/hacks/savetoweb

Re: trouble saving JPG image
Reply #6 - Oct 4th, 2007, 9:57pm
 
by the way, ... when I compare the JPG files created by "saveFrame" and the "saveasjpg" method (which doesn't quite work), it looks like that "saveFrame" includes a JFIF header inside the file, whereas the "saveasjpg" hack doesn't.

(I found this out by loading the files into BBEdit.  Among all the binary nonsense, you can see whether there is "JFIF" near the beginning of the file.)

So perhaps this observation might provide some hints for someone out there who might know how to force the JPEGEncoder to output the JFIF header.

thanks,
 djones
Re: trouble saving JPG image
Reply #7 - Oct 5th, 2007, 8:28am
 
Are you on a mac?

I found that people using the save function in applets that are on mac, usually either get the "this image can't be displayed" .. or the correct image, with a really hard, pink overlay..

I'm not sure why this happens, but It once got suggested to me that it might have something to do with Mac using CMYK by default onscreen? .. I have no experience using Macs, so I can't say for sure..

Hope this gets you closer to figuring this out

seltar
Re: trouble saving JPG image (solved)
Reply #8 - Oct 5th, 2007, 5:16pm
 
I fiddled around with the code and the following WORKS on my setup (Mac OSX 10.4.10, 2.5 GHz G5, Processing 0125).  One key seems to be selecting the pixel format as TYPE_INT_RGB, (instead of ARGB) which I presume simply ignores the Processing's Alpha channel.

-- djones

Code:
import com.sun.image.codec.jpeg.*; 
import java.awt.image.*;

void SaveJpg(String fname, float quality) {
try {
loadPixels();
ByteArrayOutputStream out = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
BufferedImage bimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bimg.setRGB(0,0,width,height,pixels,0,width);

// set JPEG quality ... with baseline optimization
JPEGEncodeParam p = encoder.getDefaultJPEGEncodeParam(bimg);
p.setQuality(quality,true);
encoder.setJPEGEncodeParam(p);

encoder.encode(bimg);
byte [] a = out.toByteArray();
saveBytes(fname,a);
}
catch (ImageFormatException e) {
println(e);
}
catch (FileNotFoundException e) {
println(e);
}
catch (IOException e) {
println(e);
}
}
Page Index Toggle Pages: 1