当前位置: 首页 > 知识库问答 >
问题:

如何使用java将PNG图像转换为灰度?

夹谷成仁
2023-03-14

我有一个关于将我的PNG图像更改为灰度的问题。我想做一个方法,接受byte[]图像作为参数,并作为byte[]返回新修改的灰度图像。

我发现了一些链接,使图像灰度与JPEG图像使用下面的片段。

private byte[] makeItGray(byte[] img, String contentType) throws IOException, Exception{


    InputStream in = new ByteArrayInputStream(img);
    BufferedImage bimg = ImageIO.read(in);

    for(int y=0; y < bimg.getHeight(); y++){
        for(int x=0; x < bimg.getWidth(); x++){
            Color color = new Color(bimg.getRGB(x,y));
            int graylevel = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
            int r = graylevel;
            int g = graylevel;
            int b = graylevel;
            int rgb = ( r<<16 ) | ( g<<8 ) | b;
            bimg.setRGB(x, y, rgb);
        }
    }

    in.close();


    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    if(contentType.equals(MediaType.IMAGE_PNG_VALUE)){
        ImageIO.write(bimg, "png", baos);
        System.out.println("PNG!!!");
    }
    else if(contentType.equals(MediaType.IMAGE_JPEG_VALUE)){
        ImageIO.write(bimg, "jpg", baos);
    }
    else
        throw new Exception();



    baos.flush();
    byte[] grayImage = baos.toByteArray();
    baos.close();

    return grayImage;
}

我的参考资料在下面:我如何使用ImageJ作为单独的Java应用程序的库?https://www.mkyong.com/java/how-to-convert-byte-to-bufferedimage-in-java/

它适用于JPEG图像,但在PNG上,它会给我发送一个透明的图像。

// converting orig image to grayscale in byte[] 
imageBytes = makeItGray(imageBytes, file.getContentType());
Path path = Paths.get("some path here that would overwrite existing image");
Files.write(path, imageBytes);

当我尝试手动打开图像以检查它是否是灰度时,它会给我透明图像或没有图像显示但不为空,因为它返回字节[]数据。我想知道上面的html" target="_blank">方法是否适用于PNG格式?

有任何问题请告诉我。谢谢!

共有2个答案

施洛城
2023-03-14
public class GrayScaleImage{
    public static void main(String[]args)throws IOException{

        BufferedImage img = null;
        File f = null;
        try{
            f = new File("D:\\Image\\image.jpg");
            img = ImageIO.read(f);
        } catch(IOExeption e){
            System.out.println(e);
        }

        int width = img.getWidth();
        int height = img.getHeight();
        for(int y = 0; y < height; y++){
            for(int x = 0; x < width; x++){
                int p = img.getRGB(x,y);
                int a = (p>>24)&0ff;
                int r = (p>>16)&0ff;
                int g = (p>>8)&0ff;
                int b = p&0ff;
                int avg = (r + g + b)/3;
                p = (a<<24) | (avg<<16) | (avg<<8) |  avg;
                img.setRGB(x, y, p);
            }
        }
        try{
            f = new File("D:\\Image\\output.jpg");
            ImageIO.write(img, "jpg", f);
        } catch(IOException e){
            System.out.println(e);
        }
傅越
2023-03-14

实际上,getRGBsetRGB方法,尽管它们的名称,实际上返回并接受32位打包ARGB格式的像素。这意味着如果您的BufferedImage的颜色模型实际上包含一个alpha通道,则像您一样将像素的alpha值留空(0x00),将导致全透明图像...

PNG格式支持alpha,而JPEG通常不使用它,这就是为什么你会看到你所做的结果,以及为什么它对不同格式的工作方式不同。

修复很简单,只是在像素值前面加上所有不透明的alpha:

int rgb = 0xff000000 | (r << 16) | (g << 8) | b;
bimg.setRGB(x, y, rgb);

如果你想保留原版的alpha,你也可以这样做(我简化了代码):

int oldrgb = bimg.getRGB(x,y);
Color color = new Color(oldrgb);
int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
int rgb = (oldrgb & 0xff000000) | (gray << 16) | (gray << 8) | gray;
bimg.setRGB(x, y, rgb);

注:请注意,通过平均值计算灰度值的方法并不是将RGB转换为灰度的推荐方法,因此与其他工具相比,您的图像可能看起来不太好。请参见将颜色转换为灰度的示例。

 类似资料:
  • 我正在尝试使用下面的函数将CGM文件转换为PNG。我一直在得到NullPointerException。 下面是我面临的例外 我尝试调试代码,发现ImageIO不支持CGM格式(CanDecodeInputFilter为我的CGM返回false)。关于如何将CGM转换为PNG图像的任何想法。 PS:我正在使用java 11进行开发。 提前感谢 使现代化 根据回复,我尝试了jcgm库(将核心和图像库

  • 问题内容: 我环顾四周,阅读文档,没有找到任何方法或解决方案,所以我在这里问。是否有可用的软件包可用于使用Python将JPG图像转换为PNG图像? 问题答案: 为此,您始终可以使用Python图像库(PIL)。可能还会有其他包/库,但是我之前曾用过它来在格式之间进行转换。 这适用于Windows下的Python 2.7(适用于Python 2.7的Python Imaging Library 1

  • 问题内容: 我正在使用aparapi编写Buddhabrot分形生成器。我将其中的OpenCL部分工作了,得到了一个表示每个像素的单维数组。我将最终图像的尺寸作为最终整数,并编写了代码以获取该数组中任意点的索引。我想将其另存为图像,并且尝试将BufferedImage与TYPE_USHORT_GRAY一起使用。这是我到目前为止的内容: 问题是,我不知道将RGB设置为什么。我需要做什么? 问题答案:

  • 问题内容: 我试图用来读取RGB图像并将其转换为灰度。 在matlab中,我使用以下代码: 在matplotlib教程中,他们没有介绍。他们只是读了图像 然后将它们切成薄片,但这与根据我的理解将RGB转换为灰度不是同一回事。 我发现很难相信numpy或matplotlib没有将rgb转换为灰色的内置函数。这不是图像处理中的常见操作吗? 我写了一个非常简单的函数,可以在5分钟内使用导入的图像。这是非

  • 问题内容: 我想将具有形状的灰度图像转换为具有形状的3通道图像。使用可以完成工作,但是必须有一个整洁的方法。这是程序中的一段代码,有人可以提示。请指教。 问题答案: 您可以使用它来更简洁地完成此操作:

  • 问题描述 (Problem Description) 如何使用Java将图像转换为灰度。 解决方案 (Solution) 以下是使用Java将图像转换为灰度的程序。 import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.img