从JPG图像中读取像素数据

时间:2016-02-02 01:18:05

标签: java image jpeg

我正在用Java读取一个简单的jpg图像并打印出像素数据的2d数组。

如果我将整个图像变黑,我会得到我所期望的: 这是10x20的黑色图像

enter image description here

结果:

 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 

然而,如果我在图像的第一行画一条白线,我会在一个我不想要的地方得到1: 另一张图片:

-1  -1  -1  -1  -1  -1  -1  -1  -1  -1 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 1  1  1  1  1  1  1  1  1  1    //Why??
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0 
 0  0  0  0  0  0  0  0  0  0

这是我的代码:

byte[][]pixels;
BufferedImage image;

public ImageProcessor(File f) throws IOException{
    image = ImageIO.read(f);
    //Bitmap bMap = BitmapFactory.decodeFile(f.getAbsolutePath());  // Si es jpg
    pixels = new byte[image.getWidth()][];

    for (int x = 0; x < image.getWidth(); x++) {
        pixels[x] = new byte[image.getHeight()];

        for (int y = 0; y < image.getHeight(); y++) {
            pixels[x][y] = (byte) (image.getRGB(x, y));
        }
    }    

}

public void printPixelMatrix(){
    for (int i = 0; i < image.getHeight(); i++) {
        for (int j = 0; j < image.getWidth(); j++) {
            System.out.print(" "+pixels[j][i] + " ");
        }
        System.out.print("\n");
    }        

}

3 个答案:

答案 0 :(得分:1)

Java没有未签名的类型,所以你的&#34; white&#34;像素是最大值(0xff),被解释为负1。

据推测,你的正面1是压缩神器。

答案 1 :(得分:1)

我怀疑你是从JPEG量化中得到一个神器。 JPEG压缩方形像素块,而不是单个像素。

查看是否有办法更改量化表。如果你将它们全部设为1,那么这应该会消失。有些编码器使用&#34;质量&#34;设置为此。使用最高质量的设置。

答案 2 :(得分:1)

我没有使用Java,所以我会使用一般的计算机图形知识......

1)首先,您可能希望为缓冲图像设置类型(即:4字节,其中R + G + B + Alpha的每个组件都有1个字节)。类似于BufferedImage.TYPE_INT_ARGB

2)我不明白为什么你试图将image.getRGB(x, y)的结果放入一个字节。从Java文档来看,似乎getRGB(x, y)返回一个数组而不是一个数字,即使这样,该数字也会将所有 ARGB 组合为一个,但一个字节只能包含一个组件的值作为最大金额(最多255,但颜色int可能类似4278254335分布在4个字节以上。

建议的解决方案:而不是字节(和步幅?),只需扫描像素并获得像素值的int。然后打印这些值。 Black = 0以及White = 4278254335。我想我的Hex格式代码可以在下面,所以它应该显示为:Black = FF000000然后White = FFFFFFFF

我认为您的最终代码应该如下所示。请修正任何错误(我发表评论,以便你看到我想要做的事)。这应该在预期的位置给你预期的黑色或黑色和白色的颜色:

//# load your old one as usual
image = ImageIO.read(f);

//# Create a new bufferdImage with type (will draw old into this) //also consider TYPE_INT_RGB
BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);

//# Then draw original into new type...
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
g.dispose(); //needed or not???

//# Doing the For-loop
int imgW = image.getWidth();
int imgH = image.getHeight();
int pixels[][] = new int[imgW][imgH]; //create a 2D array

//# Fill Array : for each [x] pos we read down /column 
//# so that we fill [y] with those pixel values
for (int x = 0; x < imgW; x++) 
{
    //On each X pos we scan all Y pixels in that column 
    for (int y = 0; y < imgH; y++) 
    {
        int col = image.getRGB(x, y);
        pixels[x][y] = col;

        //printPixelARGB( col ); //if you need this format instead of printPixelMatrix
    }
} 

//# To Print output
public void printPixelMatrix()
{
    for (int i = 0; i < image.getHeight(); i++) 
    {
        for (int j = 0; j < image.getWidth(); j++) 
        {
            //System.out.print(" " + pixels[j][i] + " ");
            int c = pixels[j][i]; //get integer that was stored in the array
            String HexVal = Integer.toHexString( c ) //giveshex value like AARRGGBB
            System.out.print(" " + HexVal + " ");
        }

        System.out.print("\n");
    }        

}

//# Another helper function to print pixel values
//# print out example blue : argb: 255, 0, 0, 255
public void printPixelARGB(int pixel) 
{
    int alpha = (pixel >> 24) & 0xff;
    int red = (pixel >> 16) & 0xff;
    int green = (pixel >> 8) & 0xff;
    int blue = (pixel) & 0xff;
    System.out.println("ARGB : " + alpha + ", " + red + ", " + green + ", " + blue);
}