【问题标题】:Scaling Image with Java produces black space使用 Java 缩放图像会产生黑色空间
【发布时间】:2014-03-29 21:21:16
【问题描述】:

我编写了以下函数来缩小图像。但是,虽然缩放有效,但生成的图像始终是方形图像,并且在图像的底部或右侧有一个黑色空间。我在这里做错了什么?

private BufferedImage scaleImageTo(BufferedImage image, int width, int height) throws Exception {
    // Fetch the width and height of the source image, ...
    int srcWidth = image.getWidth();
    int srcHeight = image.getHeight();

    // ... verify that it is larger than the target image ...
    if (srcWidth < width && srcHeight < height) {
        throw new Exception();
    }

    // ... and setup the target image with the same dimensions.
    BufferedImage scaledImage;
    if (image.getType() == BufferedImage.TYPE_CUSTOM) {
        scaledImage = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
    } else {
        scaledImage = new BufferedImage(width, height, image.getType());
    }

    // Calculate the scale parameter.
    double scale = 1;
    if (srcWidth - width >= srcHeight - height) {
        scale = ((double) width) / srcWidth;
    } else {
        scale = ((double) height) / srcHeight;
    }

    // Setup the scaling transformation ...
    AffineTransform at = new AffineTransform();
    at.scale(scale, scale);

    // ... and the transformation interpolation type.
    AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

    // Generate the scaled image  ... 
    scaledImage = scaleOp.filter(image, scaledImage);

    // ... and return it.
    return scaledImage;
}

【问题讨论】:

    标签: java image scaling bufferedimage


    【解决方案1】:

    您始终在 x 和 y 方向使用相同的比例因子。

    虽然您可以通过指定两个这样的比例因子来解决此问题

    double scaleX = (double) width / srcWidth;
    double scaleY = (double) height / srcHeight;
    AffineTransform at = new AffineTransform();
    at.scale(scaleX, scaleY);
    

    我想知道你为什么这样做。仅仅创建一个缩放版本的图像通常是相当容易的......:

    private static BufferedImage scaleImageTo(
        BufferedImage image, int width, int height) 
    {
        BufferedImage scaledImage =
            new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = scaledImage.createGraphics();
        g.setRenderingHint(
            RenderingHints.KEY_INTERPOLATION, 
            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(image, 0, 0, width, height, null);
        g.dispose();
        return scaledImage;
    }    
    

    【讨论】:

    • 是的,我总是在 x 和 y 方向上使用相同的比例因子,否则我会在不保持纵横比的情况下缩放到给定的宽度和高度。如果我总是以相同的因素拉伸,我会保留它。我作为参数给出的宽度和高度应该只限制 x 和 y 方向的大小。它类似于一个边界框。但是,我看不到您提出的扩展机制的好处。这只是另一种方法还是有一些好处。
    • @Avedo 我主要认为它更简单(而且它可能更有效,但这只是一个假设)。但是,当您说 widht/hight 应该只是“限制”大小时,您可能应该解释一下您的确切含义(可能,将其添加到原始问题中)。
    • 错误是我确实使用了边界框的宽度和高度。如果我在实际缩放之前计算缩放图像的大小,并使用这些尺寸,它会按预期工作。但是,由于您为我指明了正确的方向,并且您的答案显然是正确的,所以我接受这个。
    猜你喜欢
    • 1970-01-01
    • 2014-10-12
    • 2018-04-27
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 2017-03-13
    相关资源
    最近更新 更多