使用 Raster.getPixel 时某些图像出错
Error with some Image using Raster.getPixel
我 运行 昨天使用 BufferedImage Lib 解决了这个问题,我得到了一个
java.lang.ArrayIndexOutOfBoundsException: 3
但仅适用于图片 "PNG" 我从网上获取,但如果我在 Paint 中制作自己的图片,则一切正常。我已经尝试查找问题,但看不出我哪里错了。
package grayandconvert;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class JavaCodeProject { // remain if needed Kim
private final String PATH = "C:\New folder\"; //
private final String graypath = PATH + "oZPX0bbg.png"; // filename for Grayscale pic
private final String imgpath = PATH + "oZPX0bb.png"; // filename for Orginal pic
private final String textpath =PATH + "filename.txt"; // filename for Output textfile
private final String imgtype = "png"; // image file type for Grascale "png" "jpg"
public static void main(String[] args)
{
JavaCodeProject main = new JavaCodeProject(); //new class for use of the metoth
main.grayscale();
main.convert();
}
public void convert()
{
try
{
BufferedImage image =ImageIO.read(new File(graypath)); // called the gray pic for image
int[] pixel; // int array named pixel
System.out.print(image.getHeight());
System.out.print(image.getWidth());
for (int y = 0; y < image.getHeight(); y++) // outer forloop to control Y axel image.getWidth
{
for (int x = 0; x < image.getWidth(); x++) //inner forloop to control X axel
{
pixel = image.getRaster().getPixel(x, y, new int[3]); // gets the RGB data from the buffer
if(pixel[0]< 255 && pixel[1]< 255 && pixel[2]< 255)
{
System.out.print(" Y");
writefile("Y");
}
else
{
System.out.print(" N");
writefile("N");
}
}
System.out.print(" L");
System.out.println("");
writefile("L");
}
System.out.print("S");
writefile("S");
}
catch (IOException e) // never used it but it needs to be here
{
}
}
public void writefile(String value)
{
String array = value; //named it array. i know right :P
File file = new File(textpath); //path for new file.txt
try
{
if (!file.exists()) // if file doesnt exists, then this will create it ;)
{
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
try (BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(array,0,array.length());
}
}
catch (IOException e) // if IO exceptions happens this outputs Stacktrace
{
}
}
public void grayscale()
{
BufferedImage img = null;
try
{
File f = new File(imgpath); //org pic
img = ImageIO.read(f);
}
catch(IOException e)
{
System.out.println(e);
}
for(int y = 0; y < img.getHeight(); y++)
{
for(int x = 0; x < img.getWidth(); x++)
{
int p = img.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
//calculate average
int avg = (r+g+b)/3;
//replace RGB value with avg
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
img.setRGB(x, y, p);
}
}
try
{
File f = new File(graypath); //gray pic
ImageIO.write(img,imgtype,f);
}
catch(IOException e)
{
System.out.println(e);
}
}
}
I get the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at java.awt.image.ComponentSampleModel.getPixel(ComponentSampleModel.java:750)
at java.awt.image.Raster.getPixel(Raster.java:1519)
at grayandconvert.JavaCodeProject.convert(JavaCodeProject.java:41)
at grayandconvert.JavaCodeProject.main(JavaCodeProject.java:23)
128128C:\Users\clipcomet\Desktop\JavaApplication10\nbproject\build-impl.xml:1051: The following error occurred while executing this line:
C:\Users\clipcomet\Desktop\JavaApplication10\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 1 second)
我刚开始编程,我知道我正在使用一个我不完全了解但需要使用 BufferedImage 的 Lib,忽略我拥有的所有错误代码有人能告诉我为什么我只在某些图片上出现该错误
在某些情况下出现异常的原因是 Raster.getPixel(x, y, pixel)
试图将 像素 在 x, y 处的所有样本复制到 pixel
数组。如果您从网上下载随机图片,您无法控制光栅每个像素有多少个样本,但您将 pixel
数组硬编码为 3 个元素。
来自 API 文档(强调我的):
ArrayIndexOutOfBoundsException
- if the coordinates are not in bounds, or if iArray
is too small to hold the output.
最有可能的是,出现异常的图像有 4 个分量并且是 RGBA(而来自 Paint 的图像有 3 个分量,RGB)。您可能会通过创建更大的数组(即 new int[4]
)来摆脱异常。
然而,解决这个问题的最好方法是完全不自己创建数组,而是将其留给 getPixel
方法,如下所示:
int[] pixel = null;
for (y...) {
for (x...) {
pixel = raster.getPixel(x, y, pixel);
...
}
}
这也确保分配只发生一次,这显然有利于性能。
也就是说,您仍然需要处理这样一个事实:随机图像的每个像素可能没有预期的样本数。如果您的输入是灰色的或使用颜色图 (IndexColoModel
),它将只有一个样本(并且您的 pixel[1]
和 pixel[2]
数组将有一个 ArrayIndexOutOfBoundsExpcetion
访问)。对于颜色图的情况,样本值与您在屏幕上看到的 RGB 值无关(它只是查找的索引 table)。
出于这些原因,您可能会发现仅使用 BufferedImage.getRGB(x, y)
方法更简单、更直观,该方法 总是 为您提供像素的 ARGB 值作为单打包 int 样本,sRGB 颜色 space.
我 运行 昨天使用 BufferedImage Lib 解决了这个问题,我得到了一个
java.lang.ArrayIndexOutOfBoundsException: 3
但仅适用于图片 "PNG" 我从网上获取,但如果我在 Paint 中制作自己的图片,则一切正常。我已经尝试查找问题,但看不出我哪里错了。
package grayandconvert;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class JavaCodeProject { // remain if needed Kim
private final String PATH = "C:\New folder\"; //
private final String graypath = PATH + "oZPX0bbg.png"; // filename for Grayscale pic
private final String imgpath = PATH + "oZPX0bb.png"; // filename for Orginal pic
private final String textpath =PATH + "filename.txt"; // filename for Output textfile
private final String imgtype = "png"; // image file type for Grascale "png" "jpg"
public static void main(String[] args)
{
JavaCodeProject main = new JavaCodeProject(); //new class for use of the metoth
main.grayscale();
main.convert();
}
public void convert()
{
try
{
BufferedImage image =ImageIO.read(new File(graypath)); // called the gray pic for image
int[] pixel; // int array named pixel
System.out.print(image.getHeight());
System.out.print(image.getWidth());
for (int y = 0; y < image.getHeight(); y++) // outer forloop to control Y axel image.getWidth
{
for (int x = 0; x < image.getWidth(); x++) //inner forloop to control X axel
{
pixel = image.getRaster().getPixel(x, y, new int[3]); // gets the RGB data from the buffer
if(pixel[0]< 255 && pixel[1]< 255 && pixel[2]< 255)
{
System.out.print(" Y");
writefile("Y");
}
else
{
System.out.print(" N");
writefile("N");
}
}
System.out.print(" L");
System.out.println("");
writefile("L");
}
System.out.print("S");
writefile("S");
}
catch (IOException e) // never used it but it needs to be here
{
}
}
public void writefile(String value)
{
String array = value; //named it array. i know right :P
File file = new File(textpath); //path for new file.txt
try
{
if (!file.exists()) // if file doesnt exists, then this will create it ;)
{
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
try (BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(array,0,array.length());
}
}
catch (IOException e) // if IO exceptions happens this outputs Stacktrace
{
}
}
public void grayscale()
{
BufferedImage img = null;
try
{
File f = new File(imgpath); //org pic
img = ImageIO.read(f);
}
catch(IOException e)
{
System.out.println(e);
}
for(int y = 0; y < img.getHeight(); y++)
{
for(int x = 0; x < img.getWidth(); x++)
{
int p = img.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
//calculate average
int avg = (r+g+b)/3;
//replace RGB value with avg
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
img.setRGB(x, y, p);
}
}
try
{
File f = new File(graypath); //gray pic
ImageIO.write(img,imgtype,f);
}
catch(IOException e)
{
System.out.println(e);
}
}
}
I get the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at java.awt.image.ComponentSampleModel.getPixel(ComponentSampleModel.java:750)
at java.awt.image.Raster.getPixel(Raster.java:1519)
at grayandconvert.JavaCodeProject.convert(JavaCodeProject.java:41)
at grayandconvert.JavaCodeProject.main(JavaCodeProject.java:23)
128128C:\Users\clipcomet\Desktop\JavaApplication10\nbproject\build-impl.xml:1051: The following error occurred while executing this line:
C:\Users\clipcomet\Desktop\JavaApplication10\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 1 second)
我刚开始编程,我知道我正在使用一个我不完全了解但需要使用 BufferedImage 的 Lib,忽略我拥有的所有错误代码有人能告诉我为什么我只在某些图片上出现该错误
在某些情况下出现异常的原因是 Raster.getPixel(x, y, pixel)
试图将 像素 在 x, y 处的所有样本复制到 pixel
数组。如果您从网上下载随机图片,您无法控制光栅每个像素有多少个样本,但您将 pixel
数组硬编码为 3 个元素。
来自 API 文档(强调我的):
ArrayIndexOutOfBoundsException
- if the coordinates are not in bounds, or ifiArray
is too small to hold the output.
最有可能的是,出现异常的图像有 4 个分量并且是 RGBA(而来自 Paint 的图像有 3 个分量,RGB)。您可能会通过创建更大的数组(即 new int[4]
)来摆脱异常。
然而,解决这个问题的最好方法是完全不自己创建数组,而是将其留给 getPixel
方法,如下所示:
int[] pixel = null;
for (y...) {
for (x...) {
pixel = raster.getPixel(x, y, pixel);
...
}
}
这也确保分配只发生一次,这显然有利于性能。
也就是说,您仍然需要处理这样一个事实:随机图像的每个像素可能没有预期的样本数。如果您的输入是灰色的或使用颜色图 (IndexColoModel
),它将只有一个样本(并且您的 pixel[1]
和 pixel[2]
数组将有一个 ArrayIndexOutOfBoundsExpcetion
访问)。对于颜色图的情况,样本值与您在屏幕上看到的 RGB 值无关(它只是查找的索引 table)。
出于这些原因,您可能会发现仅使用 BufferedImage.getRGB(x, y)
方法更简单、更直观,该方法 总是 为您提供像素的 ARGB 值作为单打包 int 样本,sRGB 颜色 space.