gpt4 book ai didi

java - 在 Java 中调整 jpeg 大小时丢失颜色(尝试使用多个库)

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:00:02 24 4
gpt4 key购买 nike

我已经尝试过在 SO 上发布的多个图像大小调整库,以及使用 getScaledInstance 的原始 java。虽然大部分时间一切正常,但有两张 jpeg 图像,每当我调整它们的大小时,它们的颜色总是乱七八糟。

第一张图片:

1

结果:

2

第二张图片:

3

结果:

4

我已经使用 image.getScaledInstance() 尝试使用多个库(包括 Scalr、Thumbnailator 和 raw java)处理这些图像(代码请参见 here),但结果是一样的。

知道问题出在哪里吗?

最佳答案

this answer 的大力帮助下,我找到了解决方案:

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImgUtility
{

/**
* Takes a file, and resizes it to the given width and height, while keeping
* original proportions. Note: It resizes a new file rather than resizing
* the original one. Resulting file is always written as a png file due to issues
* with resizing jpeg files which results in color loss. See:
* https://stackoverflow.com/a/19654452/49153
* for details, including the comments.
*
*/
public static File resize(File file, int width, int height) throws Exception
{
Image img = Toolkit.getDefaultToolkit().getImage( file.getAbsolutePath() );
loadCompletely(img);
BufferedImage bm = toBufferedImage(img);
bm = resize(bm, width, height);

StringBuilder sb = new StringBuilder();
sb.append( bm.hashCode() ).append(".png");
String filename = sb.toString();

File result = new File( filename );
ImageIO.write(bm, "png", result);

return result;
}

public static BufferedImage toBufferedImage(Image img)
{
if (img instanceof BufferedImage)
{
return (BufferedImage) img;
}

BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

bimage.getGraphics().drawImage(img, 0, 0 , null);
bimage.getGraphics().dispose();

return bimage;
}

public static BufferedImage resize(BufferedImage image, int areaWidth, int areaHeight)
{
float scaleX = (float) areaWidth / image.getWidth();
float scaleY = (float) areaHeight / image.getHeight();
float scale = Math.min(scaleX, scaleY);
int w = Math.round(image.getWidth() * scale);
int h = Math.round(image.getHeight() * scale);

int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

boolean scaleDown = scale < 1;

if (scaleDown) {
// multi-pass bilinear div 2
int currentW = image.getWidth();
int currentH = image.getHeight();
BufferedImage resized = image;
while (currentW > w || currentH > h) {
currentW = Math.max(w, currentW / 2);
currentH = Math.max(h, currentH / 2);

BufferedImage temp = new BufferedImage(currentW, currentH, type);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized, 0, 0, currentW, currentH, null);
g2.dispose();
resized = temp;
}
return resized;
} else {
Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;

BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image, 0, 0, w, h, null);
g2.dispose();
return resized;
}
}


/**
* Since some methods like toolkit.getImage() are asynchronous, this
* method should be called to load them completely.
*/
public static void loadCompletely (Image img)
{
MediaTracker tracker = new MediaTracker(new JPanel());
tracker.addImage(img, 0);
try {
tracker.waitForID(0);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}

关于java - 在 Java 中调整 jpeg 大小时丢失颜色(尝试使用多个库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19659269/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com