make a thumbnail image width java - java

i wanna make a thunbnail image(resized image)
this is my code
public static void createImage(String loadFile, String saveFile)throws IOException{
File load_image = new File(loadFile); //가져오는거
FileInputStream fis = new FileInputStream(load_image);
File save = new File(saveFile); // 썸네일
BufferedImage bi = ImageIO.read(fis);
int width = bi.getWidth();
int height = bi.getHeight();
int maxWidth=0;
int maxHeight=0;
if(width>height){
maxWidth = 1280;
maxHeight = 720;
}else{
maxWidth = 720;
maxHeight = 1280;
}
if(width > maxWidth){
float widthRatio = maxWidth/(float)width;
width = (int)(width*widthRatio);
height = (int)(height*widthRatio);
}
if(height > maxHeight){
float heightRatio = maxHeight/(float)height;
width = (int)(width*heightRatio);
height = (int)(height*heightRatio);
}
BufferedImage thu = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = thu.createGraphics();
g2.drawImage(bi, 0, 0, width, height, null);
ImageIO.write(thu, "jpg", save);
}
sometimes my image colors are changed with unexpected colors
this is image example
first is origin
second is thumbnails
i don't know why...
where i mistake??
help me please...

You write your image using BufferedImage.TYPE_INT_RGB. But if this is not the type of the source image, the colors get wrong.
Try replacing this line
BufferedImage thu = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
by this:
BufferedImage thu = new BufferedImage(width, height, bi.getType());

Related

I get larger sizes after cropping the image

I have never worked with pictures in java and I am a beginner in this.
I need to make a function that will crop the images according to a certain ratio of width and height in the middle of the image.
Through REST Api I receive a MultipartFile which I pass to the image cropping function. I forward the image using file.getBytes().
Here is how I wrote the code for image crop function:
public static byte[] cropImage(byte[] data) {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
try {
BufferedImage img = ImageIO.read(bais);
int width = img.getWidth();
int height = img.getHeight();
float aspectRatio = (float) 275 / (float) 160;
int destWidth;
int destHeight;
int startX;
int startY;
if(width/height > aspectRatio) {
destHeight = height;
destWidth = Math.round(aspectRatio * height);
startX = Math.round(( width - destWidth ) / 2);
startY = 0;
} else if (width/height < aspectRatio) {
destWidth = width;
destHeight = Math.round(width / aspectRatio);
startX = 0;
startY = Math.round((height - destHeight) / 2);
} else {
destWidth = width;
destHeight = height;
startX = 0;
startY = 0;
}
BufferedImage dst = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_ARGB);
dst.getGraphics().drawImage(img, 0, 0, destWidth, destHeight, startX, startY, startX + destWidth, startY + destHeight, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(dst, "png", baos);
return baos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("IOException in scale");
}
}
But when I crop the image the result is an image with a much larger size than the received image. I need help on how to solve this problem.
EDIT:
According to this answer, the size increases on this part of the code:
ImageIO.read (bais)
Is there any other way to convert an image from byte array to buffered image but keep the size of the original image?
I don’t know why, but the problem was in part ImageIO.write(dst, "png", baos);
I was trying with different types of images (png, jpg, jpeg) and only with png did it reduce my image size. While in the situation when I changed to jpeg it reduced the size in all images.

How do you shrink an image in half in Java without using Graphics2D?

I need to write a program that shrinks an image in half without using any libraries other than Java Graphics and Java Color. I wrote one earlier with Graphics2D that looked like this --
public static void shrink(String orig, String convert) throws Exception { //Ahh damn we needed one from the red group
BufferedImage bufferedimg = null;
File f = new File(orig);
bufferedimg = ImageIO.read(f);
int width = bufferedimg.getWidth();
int height = bufferedimg.getHeight();
int finalWidth = width/2;
int finalHeight = height/2;
BufferedImage resizedImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(bufferedimg, 0, 0, finalWidth, finalHeight, null);
g.dispose();
f = new File(convert);
ImageIO.write(resizedImage, "png", f);
}
Can anyone please help?

Merge two images with different size so that they overlap correctly

I have two images with different sizes. I want to merge these two images so that the front images overlays correctly the background image.
background (width:144 height:147):
front: (width:227 height:238)
Currently my result looks like this, but i need it to overlay perfectly
My approach is.
I am resizing the smaller image to the bigger one. For that I am using the a external lib named imgscalr (https://mvnrepository.com/artifact/org.imgscalr/imgscalr-lib/4.2).
As you can see result image is not correct, so I tried to scale the front image so that it overlay the background, also I changed the root of the x / y when I draw the front image on the background but i still have a difference. Any idea how I can merge the two images, so that the strokes image (front) overlays the background.
public static byte[] mergeBackgroundWithStrokes(byte[] backgroundImage, byte[] frontImage)
throws IOException, PDProcessingException {
Path backgroundfile = readAllBytes(backgroundImage, "background");
Path outputFile = Files.createTempFile("output", ".png");
BufferedImage backgroundBuffImg = ImageIO.read(backgroundfile.toFile());
BufferedImage frontBuffImg = makeColorTransparent(frontImage, Color.WHITE);
int width = Math.max(backgroundBuffImg.getWidth(), frontBuffImg.getWidth());
int height = Math.max(backgroundBuffImg.getHeight(), frontBuffImg.getHeight());
backgroundBuffImg = resize(backgroundBuffImg, width, height);
//scaling front image
int scaledWidth = (int) ((width));
int scaledHeight = (int) ((height) * 1.02);
frontBuffImg = resize(frontBuffImg, scaledWidth, scaledHeight);
BufferedImage newImage = mergeImages(backgroundBuffImg, frontBuffImg);
ImageIO.write(newImage, "PNG", outputFile.toFile());
return Files.readAllBytes(outputFile);
}
public static BufferedImage resize(BufferedImage img, int width, int height)
{
if (img.getWidth() == width && img.getHeight() == height) {
return img;
} else {
return Scalr.resize(img, width, height);
}
}
public static BufferedImage mergeImages(BufferedImage background, BufferedImage front) {
int width = background.getWidth();
int height = background.getHeight();
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics g = newImage.getGraphics();
g.drawImage(background, 0, 0, null);
g.drawImage(front, 15, -10, background.getWidth(), background.getHeight(), 0, 0, width, height, null);
return newImage;
}
Here you can see the complete class: https://pastebin.com/F4VrBwRv

Java rotating an ImageBuffer fails

I am trying to rotate an instance of a BufferImage named pic when I try this it resizes and skews and crops the image, any advice to get it to work properly
public void rotate(double rads){
AffineTransform tx = new AffineTransform();
tx.rotate(rads,pic.getWidth()/2,pic.getHeight()/2);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
pic = op.filter(pic, null);
}
When I have it rotate 90˚ it works fine so I'm wondering if the problem is that it is the shape of the image?
For use with AffineTransform, you can square an image using something like this:
private BufferedImage getImage(String name) {
BufferedImage image;
try {
image = ImageIO.read(new File(name));
} catch (IOException ioe) {
return errorImage;
}
int w = image.getWidth();
int h = image.getHeight();
int max = Math.max(w, h);
max = (int) Math.sqrt(2 * max * max);
BufferedImage square = new BufferedImage(
max, max, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = square.createGraphics();
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawImage(image, (max - w) / 2, (max - h) / 2, null);
g2d.dispose();
return square;
}

Resizing an image in swing

I have snippet of code that I am using for the purpose of resizing an image to a curtain size (I want to change the resolution to something like 200 dpi). Basically the reason I need it is because I want to display the image that the user have picked (somewhat large) and then if the user approves I want to display the same image in a different place but using a smaller resolution. Unfortunately, if I give it a large image nothing appears on the screen. Also, if I change
imageLabel.setIcon(newIcon);
to
imageLabel.setIcon(icon);
I get the image to display but not in the correct resolution that's how I know that I have a problem inside this snipper of code and not somewhere else.
Image img = icon.getImage();
BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
boolean myBool = g.drawImage(img, 0, 0, 100, 100, null);
System.out.println(myBool);
ImageIcon newIcon = new ImageIcon(bi);
imageLabel.setIcon(newIcon);
submitText.setText(currentImagePath);
imageThirdPanel.add(imageLabel);
You don't really have to care about the details of scaling images. The Image class has already a method getScaledInstance(int width, int height, int hints) designed for this purpose.
Java documentation says:
Creates a scaled version of this image. A new Image object is returned
which will render the image at the specified width and height by
default. The new Image object may be loaded asynchronously even if the
original source image has already been loaded completely. If either
the width or height is a negative number then a value is substituted
to maintain the aspect ratio of the original image dimensions.
And you can use it like this:
// Scale Down the original image fast
Image scaledImage = imageToScale.getScaledInstance(newWidth, newHighth, Image.SCALE_FAST);
// Repaint this component
repaint();
Check this for a complete example.
Here is my solution:
private BufferedImage resizeImage(BufferedImage originalImage, int width, int height, int type) throws IOException {
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
Try this CODE to resize image :
public static Image scaleImage(Image original, int newWidth, int newHeight) {
//do nothing if new and old resolutions are same
if (original.getWidth() == newWidth && original.getHeight() == newHeight) {
return original;
}
int[] rawInput = new int[original.getHeight() * original.getWidth()];
original.getRGB(rawInput, 0, original.getWidth(), 0, 0, original.getWidth(), original.getHeight());
int[] rawOutput = new int[newWidth * newHeight];
// YD compensates for the x loop by subtracting the width back out
int YD = (original.getHeight() / newHeight) * original.getWidth() - original.getWidth();
int YR = original.getHeight() % newHeight;
int XD = original.getWidth() / newWidth;
int XR = original.getWidth() % newWidth;
int outOffset = 0;
int inOffset = 0;
for (int y = newHeight, YE = 0; y > 0; y--) {
for (int x = newWidth, XE = 0; x > 0; x--) {
rawOutput[outOffset++] = rawInput[inOffset];
inOffset += XD;
XE += XR;
if (XE >= newWidth) {
XE -= newWidth;
inOffset++;
}
}
inOffset += YD;
YE += YR;
if (YE >= newHeight) {
YE -= newHeight;
inOffset += original.getWidth();
}
}
return Image.createRGBImage(rawOutput, newWidth, newHeight, false);
}
Another example is given here :
2D-Graphics/LoadImageandscaleit.htm">http://www.java2s.com/Tutorial/Java/0261_2D-Graphics/LoadImageandscaleit.htm
http://www.java2s.com/Code/JavaAPI/java.awt/ImagegetScaledInstanceintwidthintheightinthints.htm

Categories

Resources