使用 Java 缩放图像
Scaling an image with Java
我创建了一个图像,该图像是 PDF 的摘录,并在其上制作了带有 tesseract 的 OCR。一切正常,直到决定更改图像的 dpi。我原以为这样做会出错,因此我尝试重新缩放图像以使我的 OCR 再次正常工作。
我不知道如何重新缩放图像。我知道 BufferedImage class 有一些方法,但我找不到动态调整它的方法。
我不知道我是否清楚,但想象一个 300 dpi 的图像。如果我想将它更改为 600,我必须重新缩放我的图像以使我的 OCR 再次工作,我的问题是如何动态地重新缩放它?原始 dpi 和新 dpi 之间是否存在某种比率,我可以使用它来获得新的宽度和高度?或者别的什么?
为了帮助您理解我,这里是我的代码:
public double ratioDPI() {
int ratio = 0;
int minimal_dpi = 300;
int dpi = ERXProperties.intForKey("dpi.image");
return ratio = (dpi/minimal_dpi);
}
public BufferedImage rescale(BufferedImage img) {
int width_img = img.getWidth();
int height_img = img.getHeight();
double factor_width = ERXProperties.doubleForKey("factor.size.width.image.republique.francaise");
double factor_height = ERXProperties.doubleForKey("factor.size.height.image.republique.francaise");
return (BufferedImage) img.getScaledInstance((int)(width_img*ratio), (int)(height_img*ratio), BufferedImage.SCALE_SMOOTH);
}
例如,如果更改图像的 DPI,则在将图像输出到打印机时会更改尺寸。如果将 DPI 从 300 增加到 600,则输出中的图像仅占宽度的一半和高度的一半。如果现在调整图片大小只会占用更多内存,图片质量也不会更好
缩放最好使用AffineTransform
,这样你就可以过滤图像bilinear
使像素化不那么明显:
缩放函数:
public static BufferedImage scale(BufferedImage source, double scale, boolean bilinearFiltering){
try{
BufferedImage destination = new BufferedImage((int)(source.getWidth() * scale), (int)(source.getHeight() * scale), source.getType());
AffineTransform at = new AffineTransform();
at.scale(scale, scale);
AffineTransformOp scaleOp = new AffineTransformOp(at, getInterpolationType(bilinearFiltering));
return scaleOp.filter(source, destination);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static int getInterpolationType(boolean bilinearFiltering){
return bilinearFiltering ? AffineTransformOp.TYPE_BILINEAR : AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
}
也许这是适合您的解决方案。
我创建了一个图像,该图像是 PDF 的摘录,并在其上制作了带有 tesseract 的 OCR。一切正常,直到决定更改图像的 dpi。我原以为这样做会出错,因此我尝试重新缩放图像以使我的 OCR 再次正常工作。
我不知道如何重新缩放图像。我知道 BufferedImage class 有一些方法,但我找不到动态调整它的方法。
我不知道我是否清楚,但想象一个 300 dpi 的图像。如果我想将它更改为 600,我必须重新缩放我的图像以使我的 OCR 再次工作,我的问题是如何动态地重新缩放它?原始 dpi 和新 dpi 之间是否存在某种比率,我可以使用它来获得新的宽度和高度?或者别的什么?
为了帮助您理解我,这里是我的代码:
public double ratioDPI() {
int ratio = 0;
int minimal_dpi = 300;
int dpi = ERXProperties.intForKey("dpi.image");
return ratio = (dpi/minimal_dpi);
}
public BufferedImage rescale(BufferedImage img) {
int width_img = img.getWidth();
int height_img = img.getHeight();
double factor_width = ERXProperties.doubleForKey("factor.size.width.image.republique.francaise");
double factor_height = ERXProperties.doubleForKey("factor.size.height.image.republique.francaise");
return (BufferedImage) img.getScaledInstance((int)(width_img*ratio), (int)(height_img*ratio), BufferedImage.SCALE_SMOOTH);
}
例如,如果更改图像的 DPI,则在将图像输出到打印机时会更改尺寸。如果将 DPI 从 300 增加到 600,则输出中的图像仅占宽度的一半和高度的一半。如果现在调整图片大小只会占用更多内存,图片质量也不会更好
缩放最好使用AffineTransform
,这样你就可以过滤图像bilinear
使像素化不那么明显:
缩放函数:
public static BufferedImage scale(BufferedImage source, double scale, boolean bilinearFiltering){
try{
BufferedImage destination = new BufferedImage((int)(source.getWidth() * scale), (int)(source.getHeight() * scale), source.getType());
AffineTransform at = new AffineTransform();
at.scale(scale, scale);
AffineTransformOp scaleOp = new AffineTransformOp(at, getInterpolationType(bilinearFiltering));
return scaleOp.filter(source, destination);
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static int getInterpolationType(boolean bilinearFiltering){
return bilinearFiltering ? AffineTransformOp.TYPE_BILINEAR : AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
}
也许这是适合您的解决方案。