Link to home
Start Free TrialLog in
Avatar of Triggered
Triggered

asked on

Saving a newly Created Image.

Hi,

im displying a image  i created (got from blending the two images using the sun tutorial at  http://java.sun.com/j2se/1.3/docs/guide/2d/spec/j2d-awt.fm3.html  
 ) but when i save the image using the line:

ImageIO.write(dest, "JPG", new FileOutputStream("my.jpg"));

 the colours in the saved image when reopened in photoshop/paint are completely changed, ie the saved image is totally different colorwise from the image displayed when i combined the 2 images as done in the sun tutorial.

Both Images  used to create my image are of type "JPG".

Any ideas on what i might be doing wrong,
Triggered
Avatar of GrandSchtroumpf
GrandSchtroumpf

did you try "jpg" instead of "JPG"?

ImageIO.write(dest, "jpg", new FileOutputStream("my.jpg"));
are the colors correct when you display the blended image in java?
Avatar of CEHJ
Can we just confirm here: you did actually *combine* the two new images into one did you and display the one before saving? i.e. as opposed to just displaying two images, one on top of the other?
Avatar of Triggered

ASKER


Hi GrandSchtroumpf,
yeah i tried that...made no difference though
Hi CEHJ,

I presumed they were combined , may be your right:

heres what the code im using:

 ................................................

//Note G is of type Graphics

   insets = getInsets();
  g.translate(insets.left, insets.top);
    Graphics2D g2d = (Graphics2D)g;
    Graphics2D destG = dest.createGraphics();

    destG.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC, sourcePercentage));
    destG.drawImage(coach, 0, 0, this);
    destG.setComposite(AlphaComposite.getInstance(
      AlphaComposite.XOR, destinationPercentage));
    destG.drawImage(saloon, 0, 0, this);


    g2d.drawImage(dest, 0, 0, this);

    try{
              ImageIO.write(dest, "jpg", new FileOutputStream("my.jpg"));
      }catch(Exception e){}
  }
As i said in your other thread, i'm no expert on this sort of thing, but afaik, the only image types that support alpha are png and gif. Have a crack at gif ;-)
I have tried it with gif aswell CEHJ , but i think you might be onto something about Blending VS. Combining of images
Do you view the combined image before saving to see what it actually looks like?
Hi Objects,  :-)

Yeah i combined them and displayed the image before saving it, im after fixing it now by having it as :


 g.translate(insets.left, insets.top);
    Graphics2D g2d = (Graphics2D)g;
    Graphics2D destG = dest.createGraphics();
    g2d.drawImage(dest, 0, 0, this);
    destG.drawImage(coach, 0, 0, this);
    destG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .3f));
    destG.drawImage(saloon, 25,35, this);

    try{
           ImageIO.write(dest, "PNG", new FileOutputStream("my2.png"));
    }catch(Exception e){}
  }


--------------------------------------------------------

the only problem im finding now is that the new image in PNG format is very big ( the images i combined were 2KB and 24KB respectively but the new image is 89KB+),is this is a problem related to PNG format cause ill be displaying the images on the web site, displaying 4-5 images at a time on screen would require huge bandwidth if all my images file size increse thgis much when i convert them to PNG
> the new image in PNG format is very big
this is probably because the image is not compressed.
PNG is an indexed image (like GIF).
this means that there is a palette that contains a bunch of colors that can be used in the image.
each pixel of the image is then associated with one color of the palette.

what probably happens is that the palette resulting from your merged image is much larger than the palette of the original images.
this automatically increases the size of your image file.
size of your image ~= size of the palette + (number of pixels * number of colors in your palette).

you can compress the file by reducing the number of colors in the palette.
the first thing to do is to eliminate the colors that are not used in the image (i guess it does it automatically).
then you can merge palette colors that are verry "close" from eachother.
example, you would merge (00,00,00) with (00,00,01).
this can be done with some compression algorithm that allows you to set the comression factor of you image.
look at this png encoder: http://catcode.com/pngencoder/
There must be some way to set the compression with the objects from the javax.imageio package.

There are these fields in javax.imageio.ImageWriteParam:
protected  int       compressionMode
          The mode controlling compression settings, which must be set to one of the four MODE_* values.
protected  float       compressionQuality
          A float containing the current compression quality setting.
protected  String       compressionType
          A String containing the name of the current compression type, or null if none is set.
protected  String[]       compressionTypes
          An array of Strings containing the names of the available compression types.
It would make sense to have some way to specfiy a lossless compression format, but

 ImageIO.write()

doesnt as far as i know, not sure how to use javax.imageio.ImageWriteParam()
you can have a look at the source code for PNG images:
src\com\sun\imageio\plugins\png
ASKER CERTIFIED SOLUTION
Avatar of GrandSchtroumpf
GrandSchtroumpf

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Can you post the images somewhere Triggered?

>>I guess support for png-files is still under development

Yes, i think so. If you query imageio for supported formats, png is not even given
>>size of your image ~= size of the palette + (number of pixels * number of colors in your palette).

Can this be right Grand? Surely it's

size of your image ~= size of the palette + number of pixels


?
>>size of your image ~= size of the palette + (number of pixels * number of colors in your palette).
This is not really clear i agree...
By size of the palette, i meant the space required to save the palette definition.

the formula should be more like:
size_of_your_image ~= ( number_of_indexed_colors * color_definition ) + ( number_of_indexed_colors * number_of_pixels )
thats excellent GrandSchtroumpf, say at the moment image 1(AKA starwars.jpg) is been placed over image2(AKA starwars_2.jpg)....how would i add
some tansparency to this, ie have image1 appearing transparently in the background
> thats excellent GrandSchtroumpf
i 'm happy that you're happy.
my post was meant to say that imageio did not support compression neither for png not for jpg.
however, you can specify the image depth by specifying the BufferedImage type:
https://www.experts-exchange.com/questions/20926429/Saving-PNG-Specify-bit-depth-and-resolution.html

can you manage to blend your 2 pictures correctly now?
if you want to use transparency in your final image, you need to save as png and not jpg.
how do i specify the transparency level before i combine the two images as a PNG image
i'm not an expert at transparency, sorry.
didn't you do that with this statement?
    destG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .3f));
I think it might be time for a new question now Triggered, but - quick question(s) first -

a. are you saying that the transparency thing's not working in the image result?
b. if so - does it work encoding to gif?
im using GrandSchtroumpf code for the image blending now:

--------------------------------------------------------------------------------------------------------------------------

class TestImageIO {
 
  public static void main(String[] args) throws Exception {
   
    BufferedImage image = ImageIO.read(new File ("starwars.jpg"));

    String fileSuffix = "jpg";
    Iterator writerIterator = ImageIO.getImageWritersBySuffix(fileSuffix);
    ImageWriter myImageWriter = (ImageWriter)writerIterator.next();
    System.out.println("hasNext() = " + writerIterator.hasNext());
   
    ImageOutputStream output = new FileImageOutputStream(new File ("starwars_2.jpg"));
    myImageWriter.setOutput(output);
   
    ImageWriteParam myImageWriteParam = myImageWriter.getDefaultWriteParam();
   
    int defaultMode = ImageWriteParam.MODE_DEFAULT;
    int explicitMode = ImageWriteParam.MODE_EXPLICIT;
    float quality = 0.10f;
   
    myImageWriteParam.setCompressionMode(explicitMode);
    myImageWriteParam.setCompressionQuality(quality);

    myImageWriter.write(image);
   
  }
 
}
------------------------------------------------------------------------------------------------------------------


but im unsure how to use the transparency code from program:

-----------------------------------------------------------------------
insets = getInsets();
  g.translate(insets.left, insets.top);
    Graphics2D g2d = (Graphics2D)g;
    Graphics2D destG = dest.createGraphics();

    destG.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC, sourcePercentage));
    destG.drawImage(coach, 0, 0, this);
    destG.setComposite(AlphaComposite.getInstance(
      AlphaComposite.XOR, destinationPercentage));
    destG.drawImage(saloon, 0, 0, this);


    g2d.drawImage(dest, 0, 0, this);

    try{
              ImageIO.write(dest, "jpg", new FileOutputStream("my.jpg"));
      }catch(Exception e){}
  }
---------------------------------------------------------------------

as g is a graphics object in Paint(),
not sure how i can use graphics witout using Paint()

Any Suggestions,

I can open this as a new question if ye want
sorry that should read:

"but im unsure how to use the transparency code from my program mentioned above":
Since ImageWriter does not yet support compression, you can use the ImageIO write method.
This is what i came up with, which is pretty similar to the code you posted before:

import javax.imageio.*;
import java.awt.image.*;
import java.awt.*;
import java.io.*;

class BlendImageIO {
 
  public static void main(String[] args) throws Exception {
   
    /* Modify these values to suit your needs */
    String sourceName1 = "starwars1.jpg";
    String sourceName2 = "starwars2.jpg";
    String blendedName = "blendwars.jpg";
    String blendedSuffix = "jpg";
    int    imageType = BufferedImage.TYPE_BYTE_INDEXED;
    float  alphaRatio = 0.5f;
   
    BufferedImage readImage1 = ImageIO.read(new File(sourceName1));
    BufferedImage readImage2 = ImageIO.read(new File(sourceName2));
   
    int blendedWidth  = Math.max(readImage1.getWidth(),  readImage2.getWidth());
    int blendedHeight = Math.max(readImage1.getHeight(), readImage2.getHeight());
    BufferedImage blendImage = new BufferedImage(blendedWidth, blendedHeight, imageType);
    java.awt.Graphics2D destG = blendImage.createGraphics();
   
    destG.drawImage(readImage1, 0, 0, null);
    destG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alphaRatio));
    destG.drawImage(readImage2, 0, 0, null);
   
    ImageIO.write(blendImage, blendedSuffix, new FileOutputStream(blendedName));

  }
 
}
Cheers GrandSchtroumpf, that worked perfectly