Unable to resize image and maintain transparency - java

The below code resizes an image. Unfortunately the image which is a vertical image has black bars on the sides. It looks as though the transparent, or blank space is being filled with black. I've tried setting the background color to white, and using alphaRGB but can't seem to shake it.
OrderProductAssetEntity orderProductAssetEntity = productAssets.get(jobUnitEntity.getId());
File asset = OrderProductAssetService.getAssetFile(orderProductAssetEntity);
if (asset.exists()) {
//resize the asset to a smaller size
BufferedImage resizedImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
Graphics2D g = resizedImage.createGraphics();
g.setBackground(Color.WHITE);
g.drawImage(ImageIO.read(asset), 0, 0, width, height, null);
g.dispose();
jobUnitImages.put(orderProductAssetEntity.getOriginalLocation(), new PDJpeg(document, resizedImage));
} else {
jobUnitImages.put(orderProductAssetEntity.getOriginalLocation(), null);
}

First, if you need transparency, BufferedImage.TYPE_INT_RGB won't work, you'll need BufferedImage.TYPE_INT_ARGB. Not sure if you already tried it, just want to be clear.
Second, this line:
g.setBackground(Color.WHITE);
...does only set the current background color for the graphics context. It does not fill the background with that color. For that, you'll need to do g.clearRect(0, 0, width, height) as well. But I usually prefer to use g.setColor(...) and g.fillRect(...) instead to avoid confusion.
Or, if you like, you can also use the drawImage method that takes a Color as the second last parameter like this:
g.drawImage(image, 0, 0, width, height, Color.WHITE, null);
EDIT:
Third, the class name PDJpeg implies that the image is later stored as JPEG, so you will probably lose transparency anyway. So the best is probably to stick with TYPE_INT_RGB, and fill the background with the right color (and do it the right way ;-).

Related

Drawing a circle on a bufferedImage in Java

I want to draw a circle on a buffered image that act like a png
i want to use this circle in order to replace the mouse cursor for a paint application i am working on.
i cant download a circle png from google as i need to keep changing the size of this circle depending on the width of the tool i am using it for.
here is my attempt so far
public static BufferedImage getCircle() {
BufferedImage bufferedImage = new BufferedImage(30, 30, BufferedImage.TYPE_INT_RGB);
Color transparent = new Color(0x00FFFFFF, true);
Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
//trying to make the bufferedImage transparent
g.setComposite(AlphaComposite.Src);
g.setColor(transparent);
g.setBackground(transparent);
g.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
//drawing the circle
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.black);
g.drawOval(0, 0, 200, 200);
return bufferedImage;
}
it should look like:
However my code currently only creates a white square.
Your code has two problems (as already shown in the comments). The first is that you draw a circle with a radius of 200px into an image of dimensions 30px. If you closely look you can barely see a black pixel in the lower right corner.
Fix it by adjusting your dimensions such that it fits inside, for example like:
BufferedImage bufferedImage = new BufferedImage(60, 60, BufferedImage.TYPE_INT_RGB);
...
g.drawOval(5, 5, 50, 50);
Next is that you want to achieve a transparent background. To do so you need to set the type of the image to a color model which supports transparency, like ARGB (A = Alpha = transparency) instead of RGB:
BufferedImage bufferedImage = new BufferedImage(60, 60, BufferedImage.TYPE_INT_ARGB);
Last you probably want to increase the thickness of your border to achieve the image you showed. You do so by using g.setStroke(...):
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(5));
g.drawOval(5, 5, 50, 50);
With this setting you achieve the following result (with transparency):
Play with the values to adjust the circle to your exact needs.

Is there a function that converts any image into a circle of 150x150 pixels-java?

I need a function/method that can mold(crop and resize) an imported (.png format) image into a circle of exact 150x150 pixels and it should keep transparency. I have searched all over internet, also I have my own code but I think its completely useless. I need this function for a code I am using to make GUI of a social-media app database.
private ImageIcon logo = new ImageIcon(getClass().getResource("/test/test200x200.png"));
toCircle(logo);
I need the code for the following function:
public ImageIcon toCircle(ImageIcon icon)
{
//code
return icon;
}
This function should convert this picture:
To this:
Create a new transparent image
Get a Graphics object from the image.
Set a clip for the graphics object.
Paint the PNG format image.
See also this answer that uses a clipped region.
An alternative approach, that might be more straight-forward to implement for this use case, is:
Create a transparent BufferedImage the size of your icon
Create Graphics2D from image, set hints for antialias
Fill a circle the size of your background circle
Draw the image on top of your circle, using AlphaComposite.SrcIn
Something like:
public Icon toCircle(ImageIcon logo) {
BufferedImage image = new BufferedImage(150, 150); // Assuming logo 150x150
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.fillOval(1, 1, 148, 148); // Leaving some room for antialiasing if needed
g.setComposite(AlphaComposite.SrcIn);
g.drawImage(logo.getImage(), 0, 0, null);
g.dispose();
return new ImageIcon(image);
}

Getting transparency to work in Java

I am trying to rotate an image in Java, but when I do the transparency in the png goes away. Is there any way i can rotate the image AND keep the transparency?
AffineTransform trans = new AffineTransform();
trans.setTransform(identity);
trans.translate(100, 100);
trans.rotate( Math.toRadians(45) );
gr.drawImage(image.getImage(), trans, this);
This makes the transparency in the png black, but
gr.drawImage(image.getImage(), 0, 200, null);
Has no problem with the transparency.
Try to set rendering hints on Graphics2D object.
gr.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY );
Check reference for optimal settings.

Using java, how can I make a method taking in a BufferedImage, rotate it, and return a BufferedImage ( with correct width / height )

I have been looking up a lot of examples, every time I try, my image becomes offset, and also not rotated by the degree I am looking for.
I have a class which extends JPanel, and draws an image. This JPanel is then put into my JFrame. I need to have a method, which when I click a button can take the image of the JPanel, rotate it, and return ( with the new height and width ). - Then I can ask the JPanel to repaint using the new image, and.. it should have rotated.
If someone could please help me with an example, of rotating 90 degrees, and returning with now the height = the old width, and width = old height, that would be amazing!
Thanks,
Here you are
Image rotatedImage = new BufferedImage(imageToRotate.getHeight(null), imageToRotate.getWidth(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) rotatedImage.getGraphics();
g2d.rotate(Math.toRadians(90.0));
g2d.drawImage(imageToRotate, 0, -rotatedImage.getWidth(null), null);
g2d.dispose();

Filling with transparency using Graphics2D

I created an ARGB BufferedImage. Now I'd like to reinitialize it with a transparent background. I tried the following code:
(...)
if( this.offscreen==null ||
this.offscreen.getWidth()!= dim.width ||
this.offscreen.getHeight()!= dim.height )
{
this.offscreen=new BufferedImage(
dim.width,
dim.height,
BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g=this.offscreen.createGraphics();
g.setColor(new Color(255,255,255,0));
g.clearRect(0, 0, dim.width, dim.height);
(...)
but it didn't work.
Any idea on how to do this please ?
Thanks !
g.clearRect(..) fills the selected rectangle with the background colour of the Graphics2D object. You're better off doing g.fillRect(..) which would give the intended result with your code, or set the background colour of the Graphics2D object beforehand (g.setBackground(..)).
Also, you may have to do g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC)); before the fill so that it sets the buffer properly (ignore destination buffer data, only use source data -- in this case, the fill operation). Not sure what the default is for this value, but you should set it back to that afterwards to ensure proper operation.
I had this problem before and I solved it with a really narrow trick.
Here is the deal:
In the constructor of the paint Class take a screen shot of the System but be careful
BufferedImage image = new Robot().createScreenCapture(new Rectangle(0, 23, xScreen, yScreen));
And where you want to clear the screen
g2D.drawImage(image, null, /*your Image observer*/);

Categories

Resources