Cli*_*ote 2 java bufferedimage image-manipulation
我有以下代码:
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class JavaApplication
{
public static void main(String[] args) throws Exception
{
File orig = new File ("/home/xxx/Pictures/xxx.jpg");
BufferedImage bm1 = ImageIO.read(orig);
Image scaled = bm1.getScaledInstance(100, 200, BufferedImage.SCALE_SMOOTH);
BufferedImage bm2 = toBufferedImage(scaled);
File resized = new File ("/home/xxx/Pictures/resized.jpg");
ImageIO.write(bm2, "jpg", resized);
}
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);
return bimage;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在.png文件上使用此代码,它可以正常工作,并按预期调整文件大小.但是在jpg文件上,它会产生黑色背景.
如果我删除getScaledInstance()代码并只是尝试bm1使用原来重写原始文件ImageIO.write(bm1, "jpg", resized),那就可以了.只有在调整大小getScaledInstance()然后尝试将结果转换Image回来时BufferedImage,才能获得完全黑色的背景文件.
关于如何解决这个问题的想法,或者我做错了什么?
Pet*_*ser 10
当我运行你的代码时,我没有得到黑色背景,但图像的颜色看起来很奇怪(通道似乎搞砸了).
当我改变图像类型中toBufferedImage(..),以BufferedImage.TYPE_INT_RGB(没有阿尔法,因为JPEG不支持透明度),一切工作正常.
ImageIO编写JPEG图像时没有考虑到这一点仍然很奇怪......
顺便说一句,异步图像缩放(就像getScaledInstance(..))不是问题,我确保在继续之前完成图像大小调整,这对结果没有影响.
要完全加载图像,请使用MediaTracker:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
这是我用来调整图像大小,保留比例的代码(不同的调整大小方法取决于你是升级还是降尺度,以及更快的区域平均替代方法):
public static BufferedImage resizeImage (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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3369 次 |
| 最近记录: |