How do I write a jpeg2000 with a transparent background in Java? - java

I'm using Java Advanced Imaging to read and write JPEG2000 images in java. When debugging in Intellij, I can view the BufferedImage and see that it's transparent. So I can stack layers on top of each other. But when I write it to a file, the background is always black. Is it something I'm doing wrong? Or is it the writer that's the problem? Do I need to be doing something specific with the J2KImageWriteParam regarding encoding etc? Unfortunately I'm fairly new to handling images programmatically, and there is little to no information or support for jpeg2000 that I can find.
BufferedImage image = ImageIO.read(new File("image.jp2"));
BufferedImage tmpImage = new BufferedImage(
image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE
);
Graphics2D g = (Graphics2D) tmpImage.getGraphics();
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.setComposite(AlphaComposite.Src);
g.drawImage(image, 0, 0, null);
ImageIO.write(tmpImage, "jpeg2000", new File("outputImage.jp2"));
g.dispose();

Related

Crop image by polygon area in Java

by using Canvas and JS I can draw a shape like this and have the x,y of each point :
Tha area can be choosen by more than 4 points, look at this link to have an idea.
I need to save and crop the image of the selected area by using the points. I can not use BufferedImage as it is just rectangular. Which lib in java I can use?
Okay, so starting with...
I used...
BufferedImage source = ImageIO.read(new File("Example.jpg"));
GeneralPath clip = new GeneralPath();
clip.moveTo(65, 123);
clip.lineTo(241, 178);
clip.lineTo(268, 405);
clip.lineTo(145, 512);
clip.closePath();
Rectangle bounds = clip.getBounds();
BufferedImage img = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
clip.transform(AffineTransform.getTranslateInstance(-65, -123));
g2d.setClip(clip);
g2d.translate(-65, -123);
g2d.drawImage(source, 0, 0, null);
g2d.dispose();
ImageIO.write(img, "png", new File("Clipped.png"));
to generate...
Now, the image is rectangular, that's just the way it works
Now, setClip is quite rough and isn't effect by any RenderingHints, you could make use of "soft clipping" instead, which is more involved, but generates a nicer results. See this example and this exmaple for more details

Using Java AWT to generate monochrome 1bitpp PNG with Ancillary Chunks

I am trying to generate PNG with the following ancillary chunks (header from a reference image)
The ancillary chunks in the reference image probably came from GIMP processing.
Whereas the Image I generate with Java AWT does not have those ancillary chunks.
Here is the header of the PNG I am generating. Please note the critical chunks are identical.
Here is the code fragment
{
:
// The color map contains the colors black and white
byte[] cMap = {0, 0, 0, (byte)255, (byte)255, (byte)255};
// Create an IndexColorModel setting white as the transparent color
IndexColorModel monochrome = new IndexColorModel(8, 2, cMap, 0, false, 0);
BufferedImage img = new BufferedImage(width_img, height_img,
BufferedImage.TYPE_BYTE_INDEXED,monochrome);
Graphics2D g2d = img.createGraphics();
:
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width_img, height_img);
Font font = new Font("Arial Bold", Font.PLAIN, 48);
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
g2d.setColor(Color.BLACK);
:
:
g2d.dispose();
imgName = ".\\Panel"+width_img+"x"+height_img+".png";
ImageIO.write(img, "png", new File(imgName));
:
}
How do I add chunks (pHYs, tIME) using Java AWT?
Any pointers will be helpful too- please let me know.
Thank you
I concluded that AWT does not support - this questions identifies couple of ways to add chunks
How can I save a PNG with a tEXt or iTXt chunk from Java?
Here is what I propose to do -
Use AWT / Graphics 2D to generate the .PNG
Read PNG, refer to the link for details on how to do it
Add the Chunks you want to add
Write it(them) back to the .PNG

Transparent regions of a BufferedImage are writing out black

I know this is something to do with compositing but I can't work out what. In an earlier section of code, a particular list of pixels in a BufferedImage are set to be transparent black:
for(Pixel p : closed){
Color c = new Color(image.getRGB(p.x, p.y));
Color newC = new Color(0,0,0, 0);
image.setRGB(p.x, p.y, newC.getRGB() & 0x00000000);
}
if(andCrop){
image = image.getSubimage(left, top, right-left, bottom-top);
}
return image;
Then I attempt to write the image out:
try {
BufferedImage out = new BufferedImage(image.getWidth(), image.getHeight(), java.awt.Transparency.TRANSLUCENT);
Graphics2D g2d = out.createGraphics();
g2d.setComposite(AlphaComposite.Clear);
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
g2d.setComposite(AlphaComposite.Src);
g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
g2d.dispose();
File outputfile = new File(file);
ImageIO.write(out, "png", outputfile);
} catch (IOException e) {
}
Now, I know that 'out' is clear before I attempt to draw the image onto it. What I'm not getting is what's wrong with my compositing. Instead of coming out as transparent, I'm getting full-black.
All bufferedimages used are INT_ARGB.
EDIT - This has been solved. The image source was from ImageIO.read and the BufferedImage returned did not support alpha. A quick post-read conversion let the rest of the code run smoothly.
Things that comes to my mind... (thanks to Andrew):
java.awt.Transparency.TRANSLUCENT = 3
TYPE_INT_ARGB = 2
TYPE_INT_ARGB_PRE = 3
public BufferedImage(int width,
int height,
int imageType)
Constructs a BufferedImage of one of the predefined image types. (TYPE_...)
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html
so it seems as basically it's a mixup.
Besides, what is the effect you want to achieve? you clear an empty image, then draw fully transparent pixels to it... I just don't get it.
Whelp, this has been downvoted now so I'm not sure this will be relevant, but the issue was that the original BufferedImage was being read in by ImageIO, and this image was not supporting ARGB. A quick post-read conversion allowed the rest of the code to work.

How to get rid of White rectangle from an image using java

I had tired the following code to generate the thumb nail but when I place it on another image, the thumbnail has a white rectangle. How can I remove it using java graphics 2D?
Image image = javax.imageio.ImageIO.read(new File(originalFile));
BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = thumbImage.createGraphics();
graphics2D.setBackground(Color.WHITE);
graphics2D.setPaint(Color.WHITE);
graphics2D.fillRect(0, 0, thumbWidth, thumbHeight);
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);
File file = new File(thumbnailFile);
if(javax.imageio.ImageIO.write(thumbImage, "png", file))
return file;
}
Even if i remove these three lines I am getting black rectangle.
graphics2D.setBackground(Color.WHITE);
graphics2D.setPaint(Color.WHITE);
graphics2D.fillRect(0, 0, thumbWidth, thumbHeight);
How to get this image as transparent? Please some one help me out.
Color transparent = new Color(0,0,0,0)
by setting Composite . here : AlphaComposite
// Create an image that supports arbitrary levels of transparency
Graphics2D g2d = (Graphics2D) image.getGraphics();
BufferedImage thumbImage = g2d.getDeviceConfiguration().createCompatibleImage(
thumbWidth, thumbHeight, Transparency.TRANSLUCENT);
..BufferedImage.TYPE_INT_RGB
That should be:
..BufferedImage.TYPE_INT_ARGB

Resizing photos without text .. is RenderingHints necessary?

I am writing a quick little java class that resizes an image into various smaller sizes (thumbnail large/small/etc). I have seen examples that have RenderingHints in it. The output file is significantly larger than without.
My question is: Is it necessary to use RenderingHints if the images that are being resized have no text?
int IMG_WIDTH = 100;
int IMG_HEIGHT = 100;
BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.dispose();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
I started with a 45kb image, and the output difference is a 3kb file (without RenderingHints) versus a 24kb file (with RenderingHints)
I suppose, after reading the following stackoverflow.com question/answer:
Java Text on Image
I am inclined to think that RenderingHints will provide no benefit for me when the photos contain no text ... In which case, no text = no RenderingHints = smaller resized image

Categories