调整 BufferedImages 的大小并将其存储到 JPG 图像黑色背景的文件结果中

2023-12-13

我有以下代码:

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;
      }
}

如果我在 .png 文件上使用此代码,它可以正常工作,并按预期调整文件大小。但是对于 jpg 文件,它会导致黑色背景。

如果我删除getScaledInstance()代码并尝试重写原始代码bm1到磁盘使用ImageIO.write(bm1, "jpg", resized),效果很好。仅当使用调整大小时getScaledInstance()然后尝试转换结果Image回到BufferedImage,我可以获得全黑的背景文件吗?

关于如何解决这个问题的任何想法,或者我做错了什么?


当我运行你的代码时,我没有得到黑色背景,但图像的颜色看起来很奇怪(通道似乎很混乱)。

When I 更改图像类型 in toBufferedImage(..) to BufferedImage.TYPE_INT_RGB (no alpha,因为 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);
    }
}

EDIT
这是我用来调整图像大小、保留比例的代码(不同的调整大小方法取决于您是放大还是缩小,以及更快的区域平均替代方案):

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;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调整 BufferedImages 的大小并将其存储到 JPG 图像黑色背景的文件结果中 的相关文章

随机推荐

  • phpmyadmin 中的自动增量

    我有一个使用 PHP MySQL 和 phpMyAdmin 的现有数据库 当用户成为我网站的会员时 我需要系统使用五位数字为他们创建一个唯一的会员号码 例如 83773 我想这就像生成一个随机密码 只不过我只想要我的会员的数字 该 ID 号
  • urllib2 HTTPPasswordMgr 不起作用 - 凭据未发送错误

    以下 python curl 调用具有以下成功结果 gt gt gt import subprocess gt gt gt args curl H X Requested With Demo https username email pro
  • Jenkinsfile主动选择参数

    如何在多分支管道 Jenkinsfile 声明性 中使用此 dsl 脚本 parameters activeChoiceParam States description Select a state option filterable ch
  • Ajax 如何与 PHP 配合使用?

    我在使用 ajax 和 php 时遇到问题 我想做的是调用一个 ajax 函数 该函数从表单的输入中获取一个值 并检查该电子邮件是否存在于数据库中 这是我当前的 JavaScript Checks for Existing Email fu
  • 如何同步调用ajax而不冻结网页

    我有一些 javascript 可以触发大约 100 个对 php 脚本的调用 php 脚本占用大量内存并需要几秒钟才能完成 然后返回通过或失败的 json 响应 我不希望 ajax 调用是异步的 因为服务器会在运行 100 个自身实例时突
  • 彼得森算法

    在经典的 Peterson 算法中 您在进入关键部分之前检查 2 个标志 flag1 和 flag2 以及转变量 如果我先检查转 然后检查标志 这会起作用吗 是的 如果你先检查一下 它会起作用turn然后检查flag 0 or flag 1
  • Python 断言引发用户定义的异常

    以下问题是由讨论引发的这个帖子 假设有两个文件 foob ar py and foob ar unittest py File foob ar py包含一个类 FooBar 有两个函数 foo and bar 功能bar引发内置异常 函数f
  • 如何使用 SQL 将值相乘

    好的 我正在做作业 但无法弄清楚如何与 SQL 相乘以及如何正确排序 我应该 创建一个查询 列出球员 player name 当前工资和一个新的 创建的 列 该列反映工资增加 10 计算为工资 1 1 按工资降序对数据进行排序 这只是我们老
  • 如何将包含数组的列表从 C# 序列化为 JSON?

    我希望从 C Sharp 序列化为 JSON 我希望输出是 Info item1 Count 5749 Info item2 Count 2610 Info item3 Count 1001 Info item4 Count 1115 In
  • 抽象基类的注册方法实际上做了什么?

    我对 ABC 注册方法感到困惑 采取以下代码 import io from abc import ABCMeta abstractmethod class IStream metaclass ABCMeta abstractmethod d
  • 像属性一样访问字典键?

    我发现访问字典键更方便obj foo代替obj foo 所以我写了这个片段 class AttributeDict dict def getattr self attr return self attr def setattr self a
  • 如何在渲染脚本中制作圆柱体

    我一直在尝试在渲染脚本中制作一个圆柱体 这是我尝试过的代码 public Mesh cylinder float radius 1 25f halfLength 5 int slices 16 Mesh TriangleMeshBuilde
  • 无法将控件添加到表单

    我正在尝试将用户控件添加到表单中 UserControl 与表单位于不同的项目中 但位于同一解决方案中 我过去已将此控件添加到其他表单中 但是 某些内容发生了变化 并且出现以下错误 创建组件失败MessageDisplayListContr
  • 如何从 Google Apps 脚本发布 Google 幻灯片演示文稿?

    我使用 Google Apps 脚本构建了 Google 幻灯片演示文稿 var docId DriveApp getFileById templateId makeCopy getId var newDoc DriveApp getFil
  • 分离数据并放入单独的工作表 Excel VBA [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我有一个包含超过 80K 条目的大型数据集 其形式如下 Name Date Value
  • 尝试从文本框中获取 int 时出错

    我是 C 和一般编程的新手 我能够在控制台中创建所需的程序 但也希望有一个与表单一起使用的程序 我在尝试从文本框中获取 int 时遇到了问题 在调试时我收到错误 错误 3 int 不包含 Text 的定义 并且找不到接受类型 int 的第一
  • 在 iPhone Web 应用程序中禁用滚动?

    有什么方法可以完全禁用 iPhone Web 应用程序中的网页滚动吗 我已经尝试了谷歌上发布的许多内容 但似乎都不起作用 这是我当前的标题设置 document body addEventListener touchmove functio
  • 计算 R 中列表的出现次数

    我有一个大约 100 000 次一起订购的项目的列表 我已将其粘贴到一列中 以便我可以计算每个组合出现的次数 4845 Curly Fries California Burger 1 4846 French Fries California
  • 在文本视图中显示日语而不是中文

    在textview中显示日文文本时 android默认使用中文字体 显示错误的字符 示例here 将语言环境设置为日语可以在模拟器上使用 但在我的 Galaxy s3 上不起作用 可能是因为它不支持日语 还有其他解决方案是以编程方式从资产设
  • 调整 BufferedImages 的大小并将其存储到 JPG 图像黑色背景的文件结果中

    我有以下代码 import java awt Graphics2D import java awt Image import java awt image BufferedImage import java io File import j