我正在用Java读取一个简单的jpg图像并打印出像素数据的2d数组。
如果我将整个图像变黑,我会得到我所期望的: 这是10x20的黑色图像
结果:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 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");
}
}
答案 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);
}