ImageIo watermarking jpeg with png

T

the.trav

I've got a little app that loads a jpeg from an input stream, stamps it
with a png it loaded earlier, then writes the modified jpeg to an
output stream.

It's all working and rosy, however I'm not sure it's quite as efficient
as it could be.

The basic technique I've got is to use ImageIO.read(inputStream) to get
a BufferedImage of each of the original files,

Then I create a new BufferedImage that supports alpha transparancy,
getGraphics then drawImage to draw the original, then drawImage again
to draw the watermark on top of the orginal.

Then I create a final BufferedImage that doesn't support any
transparancy and draw the stamped bufferedImage to it.

Finally I write the final bufferedImage to the output stream using
ImageIO.write(image, out);


It strikes me that I'm creating one more BufferedImage than is
necessary here,
however if I try to write the second last buffered image (the one with
alpha) to the outstream it comes out faded and with different colour
information.
If I make that buffered image without alpha to start the colour
information is correct, but the watermark is 100% opaque (binary
transparancy).

I haven't been able to find a way to convert the colour model in a
buffered image yet, and I would have thought that ImageIO could convert
it a lot better than it is doing.

I also looked into imageTranscoders, however my jre tells me that there
are no elements in the Iterator ImageIO.getImageTranscoders(pngReader,
jpegWriter);

I have also had great difficulty finding documentation on the subject
as most of the tutorials google brings back are task specific and
relate to rendering to the screen for applets and games and so forth.
 
K

Knute Johnson

I've got a little app that loads a jpeg from an input stream, stamps it
with a png it loaded earlier, then writes the modified jpeg to an
output stream.

It's all working and rosy, however I'm not sure it's quite as efficient
as it could be.

The basic technique I've got is to use ImageIO.read(inputStream) to get
a BufferedImage of each of the original files,

Then I create a new BufferedImage that supports alpha transparancy,
getGraphics then drawImage to draw the original, then drawImage again
to draw the watermark on top of the orginal.

Then I create a final BufferedImage that doesn't support any
transparancy and draw the stamped bufferedImage to it.

Finally I write the final bufferedImage to the output stream using
ImageIO.write(image, out);


It strikes me that I'm creating one more BufferedImage than is
necessary here,
however if I try to write the second last buffered image (the one with
alpha) to the outstream it comes out faded and with different colour
information.
If I make that buffered image without alpha to start the colour
information is correct, but the watermark is 100% opaque (binary
transparancy).

I haven't been able to find a way to convert the colour model in a
buffered image yet, and I would have thought that ImageIO could convert
it a lot better than it is doing.

I also looked into imageTranscoders, however my jre tells me that there
are no elements in the Iterator ImageIO.getImageTranscoders(pngReader,
jpegWriter);

I have also had great difficulty finding documentation on the subject
as most of the tutorials google brings back are task specific and
relate to rendering to the screen for applets and games and so forth.

There is an issue with colors in some PNG image files. You'll have to
search around to find it but I do remember a lot of discussions on the
subject. As to making it more efficient, read both images into the same
type of BufferedImage with transparency and draw the PNG image onto the
other. Save the the primary image any you are done. I would be curious
to see your PNG image if you want to send it.
 
D

dsjoblom

I've got a little app that loads a jpeg from an input stream, stamps it
with a png it loaded earlier, then writes the modified jpeg to an
output stream.

It's all working and rosy, however I'm not sure it's quite as efficient
as it could be.

The basic technique I've got is to use ImageIO.read(inputStream) to get
a BufferedImage of each of the original files,

Then I create a new BufferedImage that supports alpha transparancy,
getGraphics then drawImage to draw the original, then drawImage again
to draw the watermark on top of the orginal.

Then I create a final BufferedImage that doesn't support any
transparancy and draw the stamped bufferedImage to it.

Finally I write the final bufferedImage to the output stream using
ImageIO.write(image, out);


It strikes me that I'm creating one more BufferedImage than is
necessary here,
however if I try to write the second last buffered image (the one with
alpha) to the outstream it comes out faded and with different colour
information.

This happens because most jpeg libraries don't support jpegs with an
alpha channel. ImageIO is one of the few libraries capable of correctly
reading/writing jpegs with alpha.
If I make that buffered image without alpha to start the colour
information is correct, but the watermark is 100% opaque (binary
transparancy).

I'm having a little trouble parsing this sentence, but I assume you
mean you draw the watermark directly on top of the original (and the
original does not have an alpha channel). If so, I can't reproduce
this. Can you post a link to the png you are using?

Basically, the only steps you need to do are:

1. Read image (don't add an alpha component to it)
2. Draw watermark over image
3. Write image

You shouldn't need any extra copies at all. Try this program and see if
it works:

public class WaterMarkTest
{
/**
* Test driver
* @param args
*/
public static void main(String[] args)
{
if (args.length != 3)
{
System.out.println("Usage: program-name jpeg-in png-in jpeg-out");
}

try
{
BufferedImage out = ImageIO.read(new File(args[0]));
BufferedImage waterMark = ImageIO.read(new File(args[1]));

Graphics2D g = out.createGraphics();
g.drawRenderedImage(waterMark, new AffineTransform());

ImageIO.write(out, "jpg", new File(args[2]));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top