How to zoom a buffered image? - java

I am trying to create a Plagiarism checker software. Till now I have created a buffered Image which converts any text written in an text area into a png,jpg,jpeg, gif format.
When I open the image text written inside the image is shown too small and it is shown properly only when I manually zoom my screen from keyboard or Mouse.
I have tried several techniques to zoom out or reposition the image but failed. How could I achieve a zoomed in image?
Here is my Code.
String text = textArea.getText();
Font font = new Font("Tahoma", Font.PLAIN, 40);
FontRenderContext frc = new FontRenderContext(null, true, true);
//get the height and width of the text
Rectangle2D bounds = font.getStringBounds(text, frc);
int w = (int) bounds.getWidth();
int h = (int) bounds.getHeight();
String[] parts = text.split("\n");
//create a BufferedImage object
BufferedImage img = new BufferedImage(w, h * parts.length, BufferedImage.TYPE_INT_RGB);
//calling createGraphics() to get the Graphics2D
Graphics2D g = img.createGraphics();
//set color and other parameters
g.setColor(Color.WHITE);
g.setFont(font);
int index = 0;
for(String part : parts){
g.drawString(part, 4000, h * index++);
}
g.dispose();

Related

Image Thinning using JAVA

I have written some code in java to convert a colored image into black and white image and then tried to perform thinning on that gray-scale image. Black and white conversion is done successfully, but image thinning is still not giving correct output. Kindly help me in fixing my problem. My code is as follows:
//colored image to black and white conversion; black and white image to thinned image.
public static void main(String[] args)
{
try
{
//colored image path
BufferedImage colored_image = ImageIO.read(new File("D:\\logo.jpg"));
//getting width and height of image
double image_width = colored_image.getWidth();
double image_height = colored_image.getHeight();
BufferedImage img = colored_image;
//drawing a new image
BufferedImage bimg = new BufferedImage((int)image_width, (int)image_height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D gg = bimg.createGraphics();
gg.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), null);
//saving black and white image onto drive
String temp = "logo in blackAndwhite.jpeg";
File fi = new File("D:\\" + temp);
ImageIO.write(bimg, "jpg", fi);
//thinning by resizing gray scale image to desired eight and width
BufferedImage bimg2 = new BufferedImage((int)image_width, (int)image_height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = bimg2.createGraphics();
// Perform your drawing here
g2.setColor(Color.BLACK);
g2.drawLine(0, 0, 200, 200);
//saving thinned image onto drive
String temp2 = "logo thinned.jpeg";
File fi2 = new File("D:\\" + temp2);
ImageIO.write(bimg2, "jpg", fi2);
//g2.dispose();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
Check java.awt.geom.AffineTransform
AffineTransform tx = new AffineTransform();
tx.scale(20, 30);
AffineTransformOp afop = new AffineTransformOp(tx,
AffineTransformOp.TYPE_BILINEAR);
BufferedImage bi = afop.filter(ogininal, null);
Icon icon = new ImageIcon(bi); //here icon will be your thumbnail image

Rotate Buffered Image (diagonal Text)

(Sorry for the links, I'm new and I cannot post images)
I want to accomplish the following : create a table with the legends on the top, and in a diagonal way.
but I'm having some problems, I have the following image, and I'm trying to rotate it 45º (the result it's at the right),
Here is my code:
//just some labels
ArrayList<String> labels = new ArrayList<String>();
labels.add("Juan");
labels.add("QWERTYYY");
labels.add("ANA");
// margin
int margin=3;
//diagonal = 45º
// value to shift each label
int diagonalShift = (int)(cellSizeWidth / Math.sqrt(2d));
// height, width represent the size of the final image
// heightSub, widthSub represent the size of the image to be rotated taking into account the shift for each label
int widthSub = height + (diagonalShift * labels.size());
int heightSub = width;
// image to Display
BufferedImage image = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = (Graphics2D) image.getGraphics();
// tempImage: subImage to rotate and place in image
BufferedImage tempImage = new BufferedImage(widthSub, heightSub, BufferedImage.TYPE_INT_RGB);
Graphics2D tempImageGraphics = (Graphics2D) tempImage.getGraphics();
tempImageGraphics.setColor(Color.BLUE);
tempImageGraphics.drawRect(0, 0, widthSub-1, heightSub-1);
// I'd like to use antialias, but it's giving bad results
// tempImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
// drawing labels
// as we're designing a table cellSizeWidth and CellSizeHeight represent the dimensions for each cell
tempImageGraphics.setColor(Color.WHITE);
for (int i = 0; i < labels.size(); i++) {
String label = labels.get(i);
tempImageGraphics.drawString(label,
margin + (i * diagonalShift),
(int) (i * cellSizeWidth) + fontSize + centerDistance);
}
I tried the following:
//rotating
AffineTransform fontAfineTransform = new AffineTransform();
// fontAfineTransform.rotate(verticalTextDirection.rotationAngle());
which gives as result the image at the right in the second Image 2
so I need to apply a translation to get it to the right position
// Math.sqrt(2d) because I'm working with 45º and the height becomes the hypotenuse
// fontAfineTransform.translate(-height/Math.sqrt(2d),height/Math.sqrt(2d));
//drawing into image
imageGraphics.drawImage(tempImage, fontAfineTransform, null);
can someone please explain how the affineTransform works, or how can I get the text to be in a diagonal way.
Thanks

How to resize JLabel ImageIcon?

I'm making a Java Swing application that has the following layout (MigLayout):
[icon][icon][icon][....]
where icon = jlabel and the user can add more icons
When the user adds or removes icons, the others should shrink or grow.
My question is really straightforward: I have a JLabel which contains an ImageIcon; how can I resize this icon?
Try this :
ImageIcon imageIcon = new ImageIcon("./img/imageName.png"); // load the image to a imageIcon
Image image = imageIcon.getImage(); // transform it
Image newimg = image.getScaledInstance(120, 120, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
imageIcon = new ImageIcon(newimg); // transform it back
(found it here)
Resizing the icon is not straightforward. You need to use Java's graphics 2D to scale the image. The first parameter is a Image class which you can easily get from ImageIcon class. You can use ImageIcon class to load your image file and then simply call getter method to get the image.
private Image getScaledImage(Image srcImg, int w, int h){
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg, 0, 0, w, h, null);
g2.dispose();
return resizedImg;
}
And what about it?:
ImageIcon imageIcon = new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT));
label.setIcon(imageIcon);
From: Resize a picture to fit a JLabel
This will keep the right aspect ratio.
public ImageIcon scaleImage(ImageIcon icon, int w, int h)
{
int nw = icon.getIconWidth();
int nh = icon.getIconHeight();
if(icon.getIconWidth() > w)
{
nw = w;
nh = (nw * icon.getIconHeight()) / icon.getIconWidth();
}
if(nh > h)
{
nh = h;
nw = (icon.getIconWidth() * nh) / icon.getIconHeight();
}
return new ImageIcon(icon.getImage().getScaledInstance(nw, nh, Image.SCALE_DEFAULT));
}
One (quick & dirty) way to resize images it to use HTML & specify the new size in the image element. This even works for animated images with transparency.
I agree this code works, to size an ImageIcon from a file for display while keeping the aspect ratio I have used the below.
/*
* source File of image, maxHeight pixels of height available, maxWidth pixels of width available
* #return an ImageIcon for adding to a label
*/
public ImageIcon rescaleImage(File source,int maxHeight, int maxWidth)
{
int newHeight = 0, newWidth = 0; // Variables for the new height and width
int priorHeight = 0, priorWidth = 0;
BufferedImage image = null;
ImageIcon sizeImage;
try {
image = ImageIO.read(source); // get the image
} catch (Exception e) {
e.printStackTrace();
System.out.println("Picture upload attempted & failed");
}
sizeImage = new ImageIcon(image);
if(sizeImage != null)
{
priorHeight = sizeImage.getIconHeight();
priorWidth = sizeImage.getIconWidth();
}
// Calculate the correct new height and width
if((float)priorHeight/(float)priorWidth > (float)maxHeight/(float)maxWidth)
{
newHeight = maxHeight;
newWidth = (int)(((float)priorWidth/(float)priorHeight)*(float)newHeight);
}
else
{
newWidth = maxWidth;
newHeight = (int)(((float)priorHeight/(float)priorWidth)*(float)newWidth);
}
// Resize the image
// 1. Create a new Buffered Image and Graphic2D object
BufferedImage resizedImg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedImg.createGraphics();
// 2. Use the Graphic object to draw a new image to the image in the buffer
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(image, 0, 0, newWidth, newHeight, null);
g2.dispose();
// 3. Convert the buffered image into an ImageIcon for return
return (new ImageIcon(resizedImg));
}
I found that there is a minor edit to this fix from trolologuy on the last line of code, you will need to implement a new ImageIcon to get the code to compile properly (Yes I know this is 10 years ago). I found this to be an easy fix for a one off issue, but Suken Shah and Mr. Polywhirl have a better fix overall.
ImageIcon imageIcon = new ImageIcon("./img/imageName.png"); // assign image to a new ImageIcon
Image image = imageIcon.getImage(); // transform it
Image newimg = image.getScaledInstance(120, 120, java.awt.Image.SCALE_SMOOTH); // scale it smoothly
ImageIcon newImageIcon = new ImageIcon(newimg); // assign to a new ImageIcon instance

Wrapping/Rotating text on a image using graphics2D

void multiLine (int x, int y, String label, Graphics2D g) {
AffineTransform fontAT = new AffineTransform();
Font theFont = g.getFont();
fontAT.rotate(-Math.PI / 2);
Font theDerivedFont = theFont.deriveFont(fontAT);
g.setFont(theDerivedFont);
AttributedString attrStr = new AttributedString(label);
// Get iterator for string:
AttributedCharacterIterator characterIterator = attrStr.getIterator();
// Get font context from graphics:
FontRenderContext fontRenderContext = g.getFontRenderContext();
// Create measurer:
LineBreakMeasurer measurer = new LineBreakMeasurer(characterIterator,
fontRenderContext);
while (measurer.getPosition() < characterIterator.getEndIndex()) {
TextLayout textLayout = measurer.nextLayout(200);
y += textLayout.getAscent(); //Have tried changing y to x
textLayout.draw(g, x, y);
y += textLayout.getDescent() + textLayout.getLeading(); //Have tried changing y to x
}
g.setFont(theFont);
}
I am expecting this to print lines vertically but it does not , any ideas about how can I resolve this.
This outputs texts horizontally wrapped.
Edit: Changed the question to correctly reflect what I am trying to achieve
Reduce your wrapping width. 200 is too large, so it is not wrapping. Set it to 0, if you want each character on a new line.
TextLayout textLayout = measurer.nextLayout(0);

Cannot get right height of text in java.awt.BufferdImage/Graphics2D

Im creating a servlet that renders a jpg/png with a given text. I want the text to be centered on the rendered image. I can get the width, but the height i'm getting seems to be wrong
Font myfont = new Font(Font.SANS_SERIF, Font.BOLD, 400);
BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setFont(myfont);
g.setColor(Color.BLACK);
FontMetrics fm = g.getFontMetrics();
Integer textwidth = fm.stringWidth(imagetext);
Integer textheight = fm.getHeight();
FontRenderContext fr = g.getFontRenderContext();
LineMetrics lm = myfont.getLineMetrics("5", fr );
float ascent = lm.getAscent();
float descent = lm.getDescent();
float height = lm.getHeight();
g.drawString("5", ((imagewidth - textwidth) / 2) , y?);
g.dispose();
ImageIO.write(image, "png", outputstream);
These are the values I get:
textwidth = 222
textheight = 504
ascent = 402
descent = 87
height = 503
Anyone know how to get the exact height om the "5" ? The estimated height should be around 250
It's still a bit off, but much closer (288): ask the Glyph (the actual graphical representation)
GlyphVector gv = myfont.createGlyphVector(fr, "5");
Rectangle2D bounds = gv.getGlyphMetrics(0).getBounds2D();
float height = bounds.height();
Other Glyph methods (getGlyphVisualBounds, getGlyphPixelBounds, ...) return the same value. This is the region of the affected pixels when the glyph is drawn, so you won't get a better value IMO
FontRenderContext frc = gc.getFontRenderContext();
float textheight = (float) font.getStringBounds(comp.text, frc).getHeight();

Categories