I wrote a method to resize BufferedImages for me but after doing so .png images end up losing their transparency and instead they get a black background.
public BufferedImage getSizedImg(BufferedImage otherImage,int width,int height){
BufferedImage outputImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = outputImg.createGraphics();
g.drawImage(otherImage, 0, 0, width, height, null);
g.dispose();
return outputImg;
}
How can I fix the method so that the images keep their transparency?
Simple. When you create your new re-sized BufferedImage here:
BufferedImage outputImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
don't use BufferedImage.TYPE_INT_RGB but rather BufferedImage.TYPE_INT_ARGB. The "A" stands for "alpha" and this gives you the transparency. For more on this, please see the BufferedImage API.
Related
I am working on a project that involves pattern detection. I have to scale the input images to a specific size and test for pixel colour.
I tried to take in a java.awt.Image so I could resize it, then convert it to BufferedImage to test for the RGB value for each independent pixel.
However, casting BufferedImage to Image does not work.
Since java.awt.Image cannot access the color value of each individual pixel, I have to use the .getRBG functions of a BufferedImage. However, I have to take in a java.awt.Image because BufferedImage cannot be resized. I did some research about resizing the BufferedImage but all the result I found is about resizing it on screen, but not the actual image. I am NOT trying to display the BufferedImage on screen, I am trying to access the colour value of each pixel on an image.
These are the ways that could fix my issue:
Please suggest a way to...
Scale a BufferedImage (that doesn't involve drawing on the screen, just resizing the BufferedImage itself)
or
Access the colour value of a pixel in java.awt.Image
Image img = ImageIO.read(inputFile).getScaledInstance(400, 400, 0);
BufferedImage scaledImage = (BufferedImage)img;
The following code does not compile because BufferedImage cannot be cast to java.awt.Image
String imagePath = "path/to/your/image.jpg";
BufferedImage myPicture = ImageIO.read(new File(imagePath));
You can use ImageIO, check this documentation: Converting Image to BufferedImage
Or this amazing tutorial: https://www.baeldung.com/java-images
Or even this same question in 2012: Converting Image to BufferedImage
If I answer wrong your question, let me know.
For resize your image, you can try use something like that:
public static BufferedImage resize(BufferedImage img, int newW, int newH) {
Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = dimg.createGraphics();
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
return dimg;
}
this answer come from: Bufferedimage resize
While trying to scale the image drawn on a canvas, I came across Graphics2D.drawImage(originalImage) [Graphics2D object obtained from BufferedImage object].
I used it to draw the image into the graphics created from BufferedImage, this new image could be now be drawn onto a Graphics object of the Panel/Frame to get a zoomed image.
I populated the original image using BufferedImage.setRGB.
So, what is it actually doing? Is it selectively omitting the pixels from the original image?
Similar to this code.
int newImageWidth = imageWidth * zoomLevel;
int newImageHeight = imageHeight * zoomLevel;
BufferedImage resizedImage = new BufferedImage(newImageWidth , newImageHeight, imageType);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, newImageWidth , newImageHeight , null);
g.dispose();
Original Answer for the above code
Recently I have been attempting to scale pixel arrays (int[]) in Java. I used .setRGB() to add all my pixel data into the BufferedImage. BufferedImage then offers a function called .getScaledInstance(). This should work great for my purposes, but I ran into a problem. .getScaledInstance() returns a Image, not a BufferedImage. With an Image object, I cannot use .getRGB() to add all the pixel data (in int[] form) from the scaled Image back into an array. Is there a way to get raw pixel data from an Image file? Am I missing something? I looked at other questions and did a bit of googling, and they only seemed to be wanting to get picture data in a different form of array (int[][]) or in bytes. Any help would be appreciated, thanks. Also, Sprite is a class I made that is being used. Here is my code:
public Sprite scaleSprite(Sprite s, int newWidth, int newHeight){
BufferedImage image = new BufferedImage(s.getWidth(), s.getHeight(), BufferedImage.TYPE_INT_RGB);
for(int y = 0; y < s.getHeight(); y++){
for(int x = 0; x < s.getWidth(); x++){
image.setRGB(x, y, s.getPixel(x, y));
}
}
Image newImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_AREA_AVERAGING);
Sprite newS = new Sprite(newWidth, newHeight);
int[] pixels = new int[newWidth * newHeight];
newImage.getRGB(0, 0, newWidth, newHeight, pixels, 0, newWidth); //This is where I am running into problems. newImage is an Image and I cannot retrieve the raw pixel data from it.
newS.setPixels(pixels);
return newS;
}
You can draw the resulting Image onto a BufferedImage like this:
Image newImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_AREA_AVERAGING);
BufferedImage buffImg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2 = (Graphics2D) buffImg.getGraphics();
g2.drawImage(newImage, 0, 0, 10, 10, null);
g2.dispose();
Or you can scale the image directly by drawing it on another BufferedImage:
BufferedImage scaled = new BufferedImage(newWidth, newWidth, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2 = (Graphics2D) scaled.getGraphics();
g2.drawImage(originalImage, 0, 0, newWidth, newWidth, 0, 0, originalImage.getWidth(), originalImage.getHeight(), null);
g2.dispose();
The second approach will work correctly if the two BufferedImages have the same aspect ratio.
To be clear, getScaledInstance() is a method of Image, not BufferedImage. You don't generally want to revert to working directly with the Image superclass once you're working with BufferedImage; Image is really not easy to work with.
Please see if this will help: How to scale a BufferedImage
Or from Scaling a BufferedImage, where they yield the following example:
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
public class Main {
public static void main(String[] argv) throws Exception {
BufferedImage bufferedImage = new BufferedImage(200, 200,
BufferedImage.TYPE_BYTE_INDEXED);
AffineTransform tx = new AffineTransform();
tx.scale(1, 2);
AffineTransformOp op = new AffineTransformOp(tx,
AffineTransformOp.TYPE_BILINEAR);
bufferedImage = op.filter(bufferedImage, null);
}
This will give you the ability to scale entirely at the level of BufferedImage. From there you can apply whatever sprite specific or array data algorithm you wish.
I want to draw some images into a panel, I need that the images conserves their aspect ratio with the biggest dimensions to be drawn over a panel. So given the panel dimensions I must create a Java code to maximize that dimensions. The only ideas that I had needed to solve some linear programming, and I don't know how to do it in Java.
Which should be the easiest way to do what I need?
Here is the method to get a re-sized BufferedImage.
private BufferedImage resizeImage(BufferedImage originalImage, int width, int height)
throws IOException {
BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
You can use Darryl's Stretch Icon. It will dynamically resize the Icon to fill the space available to the label.
Could someone provide an example of how to dynamically create an image in Java, draw lines et cetera on it, and then draw the image so that areas not painted will remain transparent in the drawing process?
One could use a BufferedImage with an image type that supports transparency such as BufferedImage.TYPE_INT_ARGB:
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
One can draw on the BufferedImage by calling BufferedImage.createGraphics to obtain a Graphics2D object, then perform some drawing:
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
g.drawLine(0, 0, 10, 10); // draw a line.
g.dispose();
Then, since BufferedImage is a subclass of Image that can be used to draw onto another Image using one of the Graphics.drawImage that accepts an Image.