Java中将图像亮度转换为灰度错误

2023-12-11

我使用以下代码在 Java 中将图像转换为灰度:

BufferedImage originalImage = ImageIO.read(new File("/home/david/input.bmp"));
BufferedImage grayImage = new BufferedImage(originalImage.getWidth()
                                          , originalImage.getHeight()
                                          , BufferedImage.TYPE_BYTE_GRAY);

ColorSpace gray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp colorConvert = new ColorConvertOp(gray, null);
colorConvert.filter(originalImage, grayImage);

ImageIO.write(grayImage, "bmp", new File("/home/david/output_java.bmp"));

这似乎可行,但问题是输出图像与 gimp 生成的灰度图像有很大不同(请参见下面的示例)。

  1. 我可以以某种方式控制图像的生成方式吗?
  2. 如何使结果更类似于 gimp 结果?

原图:

Color original image

Java生成的灰度图像:

Gray scale image generated by ColorConvertOp

Gimp 中生成的灰度图像(Image -> Mode -> Grayscale):

Gray scale image generated in Gimp

顺便说一句:我有一堆来自 ffmpeg 的图像(带有灰色选项),它们就像 Gimp 图像,因此我希望我的图像是这种方式。


最后我写了GrayscaleFilter类实现BufferedImageOp界面。

我已经关注了这真的很好Java图像处理指南。

这是相关的代码片段:

public class GrayscaleFilter extends AbstractFilter
{
    public final static double[] METHOD_AVERAGE = {1.0/3.0, 1.0/3.0, 1.0/3.0};
    public final static double[] METHOD_GIMP_LUMINOSITY = {0.21, 0.71, 0.07};

    public GrayscaleFilter(final double[] rgb)
    {
        this(rgb[0], rgb[1], rgb[2]);
    }

    public BufferedImage filter(BufferedImage src, BufferedImage dest)
    {
        if (src.getType() == BufferedImage.TYPE_BYTE_GRAY)
        {
            dest = src;
            return dest;
        }

        if (dest == null)
            dest = createCompatibleDestImage(src, null);

        final int width = src.getWidth();
        final int height = src.getHeight();

        int[] inPixels = new int[width * height];
        GraphicsUtilities.getPixels(src, 0, 0, width, height, inPixels);
        byte[] outPixels = doFilter(inPixels);
        GraphicsUtilities.setPixels(dest, 0, 0, width, height, outPixels);
        return dest;
    }

    private byte[] doFilter(int[] inputPixels)
    {
        int red, green, blue;
        int i = 0;
        byte[] outPixels = new byte[inputPixels.length];

        for(int pixel : inputPixels)
        {
            // Obtengo valores originales
            red   = (pixel >> 16) & 0xFF;
            green = (pixel >> 8) & 0xFF;
            blue  = pixel & 0xFF;

            // Calculo valores nuevos
            outPixels[i++] = (byte)(
                 red   * red_part   +
                 green * green_part +
                 blue  * blue_part
            );
        }
        return outPixels;
    }

    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM)
    {
        return new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中将图像亮度转换为灰度错误 的相关文章

随机推荐

  • 用 Python 编写单元测试:如何开始? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我用 Python 完成了第一个正式项目 现在我的任务是为其编写测试 由于这是我第一次做一个项目 这也是我第一次为其编写测试 问题是 how我开始吗 我完全不知道 任何人都可以向
  • 有没有办法只显示基于数组的 json 对象中选定的属性

    我有以下对象 calendarLists Title titel1 Color blue number 1 Title titel2 Color green number 2 Title titel3 Color red number 3
  • SpringBoot:GenericJDBCException: 无法获取 JDBC 连接

    我通过使用以下属性动态创建 DataSource 来连接到 mysql 数据库 它工作正常 但一段时间后它不断给我错误 无法获取 JDBC 连接 package com test db import org springframework
  • 使用堆快照分析显示内存地址,但不显示代码行。如何确定导致堆增长的原因?

    我的应用程序即将完成 在提交到应用程序商店之前 我正在使用 Instruments 来优化性能 我注意到 每当我执行特定操作 从外部服务器更新应用程序中的信息 时 我的堆就会增长约 350 KB 我在 stackoverflow 和 App
  • Linq 帮助 - Sql 跟踪返回结果,但数据上下文返回 null

    var adminCov db SearchAgg AdminCovs SingleOrDefault l gt l AdminCovGuid covSourceGuid adminCov 不断返回 null 当我运行 SQL Profil
  • 如何在犰狳中序列化稀疏矩阵并与boost的mpi实现一起使用?

    我一直在尝试序列化稀疏矩阵犰狳 cpp 库 我正在做一些大规模的数值计算 其中数据存储在稀疏矩阵中 我想使用 mpi Boost 实现 收集这些矩阵并对来自不同节点的矩阵求和 我现在陷入困境的是如何将稀疏矩阵从一个节点发送到其他节点 Boo
  • 由于 windows 中的 openssl/ETimedout,gem install Rails 无法工作

    最初 我有ruby 1 9 3我的 Windows 7 中安装的版本 我已经安装了ruby 2 0 0p195最近并从命令提示符进行了测试 ruby v ruby e puts 100 irb 效果很好 ruby v gives ruby
  • 如何从 Spring Boot Endpoint Service 返回自定义 SOAP 错误?

    我已经设置了一个 Web 服务应用程序 它接收并仅记录来自第三方的 SOAP 请求 记录后必须返回定义的响应 如果没有错误并且接收到的 SOAP 请求与 WSDL 匹配 则此操作不会出现任何问题 不幸的是 第三方在发送无效内容甚至随机数据时
  • 向 CMake 添加命令行选项

    我正在使用 CMake 构建一个大型库 我希望用户能够有选择地启用 禁用构建过程的某些部分 如何将命令行选项添加到我的 CMake 构建中 例如这样用户就可以输入类似的内容cmake build partone nobuild parttw
  • Java 可视化 - 如何在 java 中转置 JTable?

    我正在寻找允许在 UI 上调换 jTable 的方法 可以通过单击按钮或其他操作来实现 我的主要问题是我应该如何为此目的构建数据模型 abstractTableModel Java中有没有现成的方法支持这种转置 如果您谈论的是行 列反转 那
  • 从 getline() 读取逗号分隔的整数

    如何从下面的代码中读取单独的整数 while getline cin line for each integer in line do something myVector push back each integer 输入是这样的 1 2
  • 如何捕获 Laravel 5 中的异常/缺失页面?

    在 Laravel 5 中 App missing and App error不可用 那么你现在如何捕获异常和丢失页面呢 我在文档中找不到与此相关的任何信息 在 Laravel 5 中 您可以通过编辑以下内容来捕获异常render中的方法a
  • 检查输入是否是有效的罗马数字

    我有一个程序可以将罗马数字转换为整数 反之亦然 我的问题是我真的不知道如何创建一个函数来检查用户输入是否是有效的罗马数字 我现在的代码 def checkIfRomanNumeral numeral Controls that the us
  • 尽管 KEEPALIVE,TCP、recv 函数仍挂起

    在服务器挂掉后 TCP keepalive 具有较小的超时 是否会阻止客户端挂在接收上 场景 服务器和客户端运行在不同的机器上 客户端通过带有 KEEPALIVE 选项的 TCP 连接到服务器 客户端发送 Hello server 并等待响
  • 不同类型的指针赋值

    我们可以在 C 中分配一个字符串 如下所示 char string string Hello printf s n string string printf p n string memory address 一个数字可以按如下方式完成 i
  • Passport.js 验证用户身份时出现问题

    我无法获取 Passport 来验证我的用户 由于某种原因 passport authenticate 方法总是失败 我不明白的是 如果我在护照调用之前添加中间件 则可以通过以下方式访问用户数据req user 关于为什么 Passport
  • Oracle 11.1.0.7 和 WAMP oci_connect 失败

    我正在尝试在我的本地 WAMP 服务器和我拥有的一些 Oracle 11 1 0 7 之间配置一个简单的连接 显然 PHP 有各种无法启动的解决方案和神奇情况 我正在运行 WAMP 的最新 32 位版本 我今天再次获取它只是为了检查 数据库
  • 如何创建网络服务

    我使用 Ruby on Rails 框架构建了一个网站 该站点将包含一个 Flash 应用程序 该应用程序将使用 Web 服务与 Rails 应用程序进行交互 我的合作伙伴构建了 Flash 应用程序 他告诉我 Flash 应用程序通过 W
  • 使用R中的mat2listw函数创建空间权重矩阵

    我正在尝试使用 mat2listw 函数在 R 中创建一个权重对象 我有一个非常大的空间权重矩阵 大约 22 000x22 000 这是在 Excel 中创建并读入 R 的 我现在正在尝试实现 library spdep SW mat2li
  • Java中将图像亮度转换为灰度错误

    我使用以下代码在 Java 中将图像转换为灰度 BufferedImage originalImage ImageIO read new File home david input bmp BufferedImage grayImage n