Using data in BufferedImage that is drawn by Graphics - java

I have the method below:
private Graphics getBufferedImage(Image image) {
// Create empty BufferedImage, sized to Image
buffImage =
new BufferedImage(
image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
// Draw Image into BufferedImage
Graphics wholeImage = buffImage.getGraphics();
return wholeImage;
}
It takes an Image and tries to generate the BufferedImage with a Graphics object.
What can I do with this Graphics (or BufferedImage) to actually let me use it? I'm using GIF files.
Would it be easier to use a byte array to transfer Image data over?
Cheers,
Alex

You can get OutputStream object using method ImageIO.write(...). Now you can transfer it over the network or save to file or store to array or something else.

You can use Graphics.drawImage to draw the original image in the new image. In fact you can use any operation that Graphics offers, as well as cast it to Graphics2D (because that's what it is) and use those operations too.

Related

How to set a pixel in a BufferedImage To Transparent

I'm Currently making a Game, and I need to set a couple Pixels of a BufferedImage (loaded using ImageIO.read) to be transparent in the fastest, best way.
I can't really find any other topic with this question, and If I do the answer Doesn't really help/fit What I need.
Thanks :)
Use Color(red, green, blue, alpha) with values 0-255. Where alpha is the opacity.
Buffed image being of type with an Alpha channel (RGBA, BGRA)
Color halfTransparant = new Color(0x76, 0x54, 0x32, 128);
With setRGB on arrays this still is not fast, you might access the raster data.
But why using dynamically generated images in time critical situations.
The smart way is to create your image with correct alpha from the start (using an image format with transparency, e.g. PNG and your favorite imaging application e.g. GIMP).
Otherwise you can directly alter pixels in the BufferedImage returned by ImageIO using the BufferedImage API: setRGB(int ARGB) and its bulk manipulation cousins in the BufferedImage's Raster.
One way that should work with all image types (as long as they support alpha), is very fast, and will not disable hardware acceleration of the image is:
BufferedImage image = ...; // From somewhere
Graphics2D g = destination.createGraphics();
try {
g.setComposite(AlphaComposite.Clear);
g.fillRect(x, y, w, h); // Area to make transparent
}
finally {
g.dispose();
}

How to create a Buffered Image of the content drawn on a Canvas?

I have a canvas on which I am adding primitive shapes like square, circles etc. Is it possible to get the content drawn on the canvas in form of a Buffered Image.
I actually aim to access single pixels from the canvas, and couldn't find a better way of doing this?
Try this approach:
1.) Create a bufferedimage the width and height of the canvas
2.) Create a graphics2D object from the new bufferedimage
3.) Use the paint(g2d) or paintall(g2d) method of your canvas object
So you have something like:
BufferedImage myBI = new BufferedImage(myCanvas.getWidth(), myCanvas.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = myBI.createGraphics();
myCanvas.paint(g);
Your canvas should now be painted into the bufferedimage.
The question of whether to draw from a canvas to a bufferedimage or to draw from a bufferedimage to a canvas has to do with speed and with image quality. Drawing to buffered image is faster than drawing to canvas, but that might not matter if you are just doing this for static images. But you may also notice a difference in image quality. I have printed jpanels to buffered image and then to jpg files, and have noticed reduced image quality.

hasAlpha vs getAlphaRaster

In Java, is it expected to be able to have a BufferedImage such that getColorModel().hasAlpha() will return true, but getAlphaRaster() will return null?
I ask because there's a library I'm using (PDFBox specifically, in the PDJpeg class) that breaks on such an image.
In this particular case I'm creating the image very simply using:
BufferedImage bi = ImageIO.read(new FileInputStream("/Users/dan/Downloads/test.png"));
I've attached the particular image that's failing for me below this question.
Is there some sort of parameter I can pass to ImageIO or some kind of transformation I can do to my BufferedImage after it's loaded so that it won't run into this problem?
I'm running Java 1.7.0_40 if it matters.
Stack trace for completeness:
java.lang.NullPointerException
at java.awt.image.ComponentColorModel.isCompatibleRaster(ComponentColorModel.java:2787)
at java.awt.image.BufferedImage.<init>(BufferedImage.java:629)
at org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg.createImageStream(PDJpeg.java:159)
at org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg.<init>(PDJpeg.java:133)
Yes. As the JavaDoc states:
This method assumes that for all ColorModel objects other than IndexColorModel, if the ColorModel supports alpha, there is a separate alpha channel which is stored as the last band of image data. If the image uses an IndexColorModel that has alpha in the lookup table, this method returns null since there is no spatially discrete alpha channel.
Your image is a palette PNG with a transparent index. ImageIO will read this into a BufferedImage with IndexColorModel (ie., no discrete alpha channel).
You can convert the image to a different BufferedImage type (like TYPE_INT_RGB), by creating a blank image of the same size, getting its graphics, and draw the original onto it:
BufferedImage origininal = ...;
BufferedImage copy = new BufferedImage(original.getWidth(), original.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = copy.createGraphics();
try {
g.drawImage(original, 0, 0, null);
}
finally {
g.dispose();
}
You can probably also pass the image type as an ImageTypeSpecifier on the ImageReadParam passed to the ImageReader. But it requires quite a bit more code for the reading part.

How do i apply a PerspectiveTransform to graphics object or image?

I'm trying to draw a square image into a trapezoid using the Java Advanced Imaging API; However after creating a PerspectiveTransform I am unsure how I would go about applying it to a graphics object or image.
When you apply a JAI operation, get RenderedOp, whichever operation (PerspectiveTransform, Scale...) as result. This represents the operation in a chain if you apply several operations to the same image, so the next operation is applied over the RenderedOp and so on. Finally, you need to draw it, so:
1) Convert it to RenderedImage in order to apply all calculations to the final image. Use something like:
new BufferedImage(renderedOp.getColorModel(), renderedOp.copyData(), false, null);
2) Draw the image onto a Graphics using something like:
Graphics2D graphics2D = (Graphics2D)graphics; // Convert the graphics received to Graphics2D to get more operations.
graphics2D.drawRenderedImage(renderedImage, new AffineTransform());

Resizing TYPE_CUSTOM BufferedImages?

When I read a JPEG from disk, Java sometimes gives me a BufferedImage whose getType() returns TYPE_CUSTOM -- that is, it has a custom color model. I'd like to resize this BufferedImage but I'm not sure how to construct the destination object. Can someone please provide sample code for using the following constructor?
BufferedImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable properties)
I would like to create a BufferedImage of the same type as the source, just bigger, and transfer the contents over. Any ideas?
Answering my own question, it looks like ImageTypeSpecifier is the answer. Specifically:
Invoke ImageTypeSpecifier.createFromRenderedImage(RenderedImage image) to get back an ImageTypeSpecifier from the image with the custom color model.
Invoke ImageTypeSpecifier.createBufferedImage(int width, int height) on the ImageTypeSpecifier from step 1 to create a new image with the same color model as the original image.

Categories