Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 2D图像大小调整忽略双三次/双线性插值渲染提示(OS X+;linux)_Java_Image_Resize_2d_Bicubic - Fatal编程技术网

Java 2D图像大小调整忽略双三次/双线性插值渲染提示(OS X+;linux)

Java 2D图像大小调整忽略双三次/双线性插值渲染提示(OS X+;linux),java,image,resize,2d,bicubic,Java,Image,Resize,2d,Bicubic,我正在尝试使用Image Voodoo插件在JRuby/Rails应用程序中创建上传图像的缩略图-问题是大小调整后的缩略图看起来像。。。屁股 生成缩略图的代码似乎完全正确地将插值渲染提示设置为“bicubic”,但在我们的开发环境(OS X)或生产web服务器(Linux)上,它并没有尊重它们 我提取了生成缩略图的代码,将其重写为一个直接的Java应用程序(即从main()方法开始),插值渲染提示显式设置为“双三次”,并重现了(缺少)双三次和双线性的大小调整 正如在OSX和Linux上所预期的那

我正在尝试使用Image Voodoo插件在JRuby/Rails应用程序中创建上传图像的缩略图-问题是大小调整后的缩略图看起来像。。。屁股

生成缩略图的代码似乎完全正确地将插值渲染提示设置为“bicubic”,但在我们的开发环境(OS X)或生产web服务器(Linux)上,它并没有尊重它们

我提取了生成缩略图的代码,将其重写为一个直接的Java应用程序(即从main()方法开始),插值渲染提示显式设置为“双三次”,并重现了(缺少)双三次和双线性的大小调整

正如在OSX和Linux上所预期的那样,拇指图案丑陋且像素化,但在Windows上,它通过使用双三次插值很好地调整了图像的大小


我是否缺少任何JVM环境设置和/或其他库来让它工作?这一次我的头撞了很多墙。

也许这是你的解决方案:

public BufferedImage resizeImage(BufferedImage source, int width, int height)
{
     BufferedImage result = new BufferedImage(widht, height, BufferedImage.TYPE_INT_ARGB);
     Graphics g = result.getGraphics();
     g.drawImage(source, 0, 0, widht, height, null);
     g.dispose();
     return result;
}

最后,升级到ImageVoodoo的最新版本似乎提高了质量

通过查看源代码,看起来他们正在进行一些时髦的AWT渲染,然后将其拉出。很恶心,但似乎有效


仍然不如ImageMagick好,但比以前好多了。

我意识到这个问题是前一段时间提出的,但万一还有其他人遇到这个问题

缩略图看起来像屁股的原因有两个原因(主要是第一个原因):

  • Java中的非增量图像缩放非常粗糙,会抛出大量像素数据,并将结果平均一次,而不考虑渲染提示
  • 在Java2D(通常是GIF)中处理受支持较差的BuffereImage类型可能会导致非常差的外观/抖动结果
事实证明,旧版在制作美观的缩略图方面做得不错,但速度慢,Java2D团队不赞成使用它——不幸的是,他们没有用任何现成的替代品来取代它,让我们有点孤立无援

Chris Campbell(来自Java2D团队)几年前用增量缩放的概念解决了这一问题——与其在一次操作中从初始分辨率转换为目标分辨率,不如分步执行,结果看起来更好

考虑到这方面的代码相当大,我将所有最佳实践编写到一个名为的库中,并在Apache2许可证下发布了它

最基本的用法如下所示:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 640);
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
                                       150, 100, Scalr.OP_ANTIALIAS);
在本用例中,库使用所谓的“自动”缩放模式,并将结果图像(尊重其比例)放在640x640的边界框内。因此,如果图像不是正方形,并且是标准的4:3图像,它会将其大小调整为640x480——参数只是它的最大尺寸

上还有许多其他方法(都是静态的,易于使用),允许您控制一切

为了获得尽可能美观的缩略图,命令如下所示:

BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 640);
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
                                       150, 100, Scalr.OP_ANTIALIAS);
Scalr.OP_ANTIALIAS是可选的,但许多用户认为,在Java中,当您缩小到足够小的缩略图时,像素值之间的一些转换过于离散,使图像看起来“清晰”,因此许多用户要求有一种方法来稍微软化缩略图

如果您以前从未使用过它们,那么尝试找出正确的“内核”是。。。这是一个让人头疼的问题。在类上定义的OP_抗锯齿常量是我与另一个用户测试一周后发现的最漂亮的抗锯齿OP,该用户在巴西的社交网络中部署了imgscalr(用于缩放个人资料照片)。我把它包括进来是为了让每个人的生活更轻松一点

此外,在所有这些例子中,您可能已经注意到,当您缩放GIF和其他类型的图像(BMP)时,有时缩放结果与原始图像相比看起来很糟糕。。。这是因为图像的BuffereImage类型不受支持,而Java2D使用其软件渲染管道,而不是硬件加速的管道,以获得更好的支持图像类型

imgscalr将为您解决所有这些问题,并尽可能将映像保持在受支持的最佳映像类型中,以避免出现这种情况


不管怎么说,要说“你可以使用imgscalr为你做所有这些,而不必担心任何事情”还有很长的路要走。

@Riyad,增量缩放的代码不是“相当大”,它相当小(正如你在2007年的一篇文章中看到的),拥有一个提供其他选项的库可能很有用,但是用图书馆来使用图书馆是胡说八道。

好吧,至少我从这本书里摘掉了“滚翻杂草”的徽章。考虑一下用一个系统imagemagick进程代替。非常酷的库,图像质量的差异马上就明显了。不过,我注意到了一些有趣的事情——当我尝试将此图像调整为134 x 100时,Scalr.resize调用会给我一个99像素高的图像,而不是100像素高的图像。我使用的是您列出的“Method.QUALITY”示例,但在附加标志的情况下,它仍然短一个像素。知道为什么吗?resize调用都采用“目标”大小-但imgscalr不会扭曲图像,这意味着它首先计算出比率,然后尽可能将图像调整为目标大小,而不会违反它。如果不违反其中一个维度,图像可能无法制作为134x100,因此它将制作为134x99。因此,如果你传入,例如200x30,对于该图像,它会将图像粉碎成任何最小的框,以正确的比例放入该框中。这就是为什么如果你只是针对一个共同的宽度,你可以只通过在“200”为例。鉴于图像的大小比是相同的图像的前一个ra