在Java中调整jpegs大小时丢失颜色(尝试使用多个库)
发布时间:2020-12-14 05:12:34 所属栏目:Java 来源:网络整理
导读:我已经尝试过在SO上发布的多个图像调整库,以及使用getScaledInstance的raw java.虽然一切都在大部分时间工作,但是有两个jpeg图像,每当调整大小时,颜色总是被弄乱. 第一张图片: 结果: 第二张图片: 结果: 我已经尝试过这些图像与多个库,包括Scalr,Thumbnai
我已经尝试过在SO上发布的多个图像调整库,以及使用getScaledInstance的raw
java.虽然一切都在大部分时间工作,但是有两个jpeg图像,每当调整大小时,颜色总是被弄乱.
第一张图片: 结果: 第二张图片: 结果: 我已经尝试过这些图像与多个库,包括Scalr,Thumbnailator和raw java使用image.getScaledInstance()(参见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,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,currentW,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,w,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 – Spring – server.connection-timeout无效
- java – 如何在jruby9.1.2.0中使用gpg加密加密文件?
- javax.net.ssl.SSLHandshakeException
- 如何将Java与nodej进行集成来处理CPU重的任务?
- JDK8的java.time是否有jackson数据类型模块?
- java – 即使明确禁用反序列化,Jackson ObjectMapper也会将
- java – 如何创建一个非常大的BigInteger
- java – Performance Encog vs Deeplearning4J
- 使用Java(JSON)读取JSON中嵌套键的值
- 两个java文件,在同一目录中,一个访问其他类/ s?