RGB至灰度,Java中的bmp图像 [英] RGB to Grayscale, bmp image in java

查看:200
本文介绍了RGB至灰度,Java中的bmp图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的老师给了我们一个任务,使班级学习一个640x480 bmp彩色图像,并将其转换为灰度图像,我发现了一些有想法的资源,所以我做到了。但这是有问题的,因为它似乎使它没有引起错误,但没有出现输出。我认为这是我的代码。我的代码是

My teacher gave us a task to make a class that takes an 640x480 bmp colored image, to convert it in grayscale image, I found some sources with ideas so i did it. But there's a problem because it seems that it makes it cause it doesn't give me error, but the output doesn't appear. I think it's my code. My code is

import java.io.*;

public class Grayscale{

FileInputStream image;
FileOutputStream img;
byte[] datos;
int gray;

public Grayscale(String nombre)throws Exception{

    this.image = new FileInputStream(nombre);
    this.img = img;
    this.datos = new byte[image.available()];
    this.gray = gray;
}

public void gray()throws Exception{

    image.read(datos);
    img = new FileOutputStream("grayscaleprueba.bmp");

    for (int i = 0; i<datos.length; i++){
        gray = (byte)(datos[i]*0.3 + datos[i+1]*0.59 + datos[i+2]);
        datos[i] = (byte)gray;
        datos[i+1] = (byte)gray;
        datos[i+2] = (byte)gray;
    }

    img.write(datos);
}
}


推荐答案

有除了@joni提到的问题,还有一些问题。这个问题比它最初看起来要深一些。

There are some problems apart from those that @joni mentioned. This problem is a bit deeper than what it first seems to be.


  • BMP格式具有标头。在进行图像转换之前,您应该跳过(或可能更新)标题。

  • 颜色表:您假设一个直线调色板:颜色索引与RGB值相同。但这可能有所不同...(顺便说一句:,如果图片使用了颜色表,则只能对其进行更改以获取灰度图像...)

  • 每个像素有多少位?您假定它是每个像素24位,分布为8-8-8。这不保证...标头提供了此信息。

  • 压缩:是的,图像可能会被压缩-您必须对其进行解码才能对像素值本身进行任何处理。

  • The BMP format has a header. You should skip (or probably update) the header before doing the image transformation.
  • color table: you assume a "straight" palette: the color index the same as the RGB value. But this might be different... (BTW: If the picture uses a color table, then you could alter only that to get a grayscale image however...)
  • how many bits per pixel are there? You assumed that it is 24 bits per pixel, in a 8-8-8 distribution. This is not guarranteed... The header provides this info.
  • compression: yep, the image might be compressed - you'd have to decode it to do anything with the pixel values themselves.

每个像素处理3个字节,然后以1为增量在文件中循环播放。通过3D眼镜观看时,生成的图像可能很有趣,但是将显示一些奇怪的图像。

You deal with 3 bytes for each pixel, and you loop through the file in the increments of 1. The resulting image might happen to be quite interesting to watch through 3D glasses, but will mean some strange image appearing.

for (int i = 0; i<datos.length; i+=3){ // increment by 3 instead of 1
    gray = (byte)(datos[i]*0.3 + datos[i+1]*0.59 + datos[i+2]);
    datos[i] = (byte)gray;
    datos[i+1] = (byte)gray;
    datos[i+2] = (byte)gray;
}



签名字节



Java中的字节已签名。它从-128变为127,因此您的算术无效。对于每个字节,我都将其用作整数,并在对它们进行权重求和之前将其添加128。然后求和,然后减去128,然后转换为字节。

Signed byte

Byte in Java is signed. It goes from -128 to 127, so your arithmetic is not valid. For each byte, I'd use it as an int, and add 128 to it before summing them with weights. Then after summing, subtract the 128, and then cast to byte.

您求和在saem范围内最多3个数字,并且想要获得范围内的数字。但是,您的权重并不能反映这一点:权重应该加起来为1。对于初学者来说,我将所有值都使用0.33(这不能给出完美的颜色权重,但从技术上讲应该可以)。

You sum up 3 numbers in the saem range, and would want to get a number in the range itself. However, your weights don't reflect this: the weights should add up to 1. For starters, I'd use 0.33 for all values (that does not give perfect color weights,but should technically works).

    //using double to have some precision
    double temp = datos[i]/3.0d + datos[i+1]/3.0d + datos[i]/3.0d;
    gray = (byte)(Math.round(temp)-128); //rounding to Long, and converting to byt value range

这篇关于RGB至灰度,Java中的bmp图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆