Java ImageIO正在读取RGB而不是ARGB数据
我正在为一个照片编辑器开发一个GUI,目前我正忙于从一个文件中加载一个32位BMP图像。在我开始尝试多层并将其成型为一层之前,一切都进展顺利。采用C++(exe文件)< /P>运行时类(图层造型和图像保存) 我使用pixelFormer软件制作了一个简单的300x300红色bmp图像,每个像素的值为R:255g:0b:0a:125 我注意到我下面的方法加载了一个RGB,其中alpha通道的默认值为255,其中125应该是。这是:Java ImageIO正在读取RGB而不是ARGB数据,java,image,pixel,bmp,Java,Image,Pixel,Bmp,我正在为一个照片编辑器开发一个GUI,目前我正忙于从一个文件中加载一个32位BMP图像。在我开始尝试多层并将其成型为一层之前,一切都进展顺利。采用C++(exe文件)< /P>运行时类(图层造型和图像保存) 我使用pixelFormer软件制作了一个简单的300x300红色bmp图像,每个像素的值为R:255g:0b:0a:125 我注意到我下面的方法加载了一个RGB,其中alpha通道的默认值为255,其中125应该是。这是: public void readFile(String sourc
public void readFile(String sourceFileName, Image image) throws IOException {
ArrayList<Short> pixels = new ArrayList<>();
try {
BufferedImage img = ImageIO.read(getClass().getResource(sourceFileName));
System.out.println(img.getType());
for (int i =0;i<img.getHeight();i++)
for (int j =0;j<img.getWidth();j++)
{
Color c = new Color(img.getRGB(j,i),true);
pixels.add((short)(c.getRed()));
pixels.add((short)(c.getGreen()));
pixels.add((short)(c.getBlue()));
pixels.add((short)(c.getAlpha()));
System.out.println("argb: " + c.getAlpha() + ", " + c.getRed() + ", " + c.getGreen() + ", " + c.getBlue());
}
image.loadLayer(new Layer(img.getHeight(),img.getWidth(),pixels));
} catch (IOException e)
{
//
}
实际读者:
void BMPFormater::read(std::string sourceFileName)
{
{
std::ifstream input{ sourceFileName, std::ios_base::binary };
if (input)
{
BMPFileHeader fileHeader; // struct instance
BMPInfoHeader infoHeader; // struct instance
BMPColorHeader colorHeader; // struct instance
uint32_t row_stride{ 0 };
input.read((char*)&fileHeader, sizeof(fileHeader));
if (fileHeader.fileType != BMPID) {
throw std::runtime_error("Error! Unrecognized file format.");
}
input.read((char*)&infoHeader, sizeof(infoHeader));
this->bitsPerPixel= infoHeader.bitsPerPixel;
this->height=infoHeader.height;
this->width=infoHeader.width;
if (infoHeader.height < 0)
throw std::runtime_error("The program can treat only BMP images with the origin in the bottom left corner!");
// Jump to the pixel data location
input.seekg(fileHeader.data_offset, input.beg);
this->pixels.resize(this->width * this->height * this->bitsPerPixel / 8);
// Here we check if there is a need to take into account row padding
if (infoHeader.width % 4 == 0)
input.read((char*)this->pixels.data(), this->pixels.size());
else {
row_stride = infoHeader.width * infoHeader.bitsPerPixel / 8;
// uint32_t new_stride = 0;
uint32_t new_stride = row_stride;
while (new_stride % 4 != 0)
new_stride++;
std::vector<uint8_t> padding_row(new_stride - row_stride);
for (int y = 0; y < infoHeader.height; ++y) { //cita red po red i svaki red peduje
input.read((char*)(this->pixels.data() + row_stride * y), row_stride);
input.read((char*)padding_row.data(), padding_row.size());
}
}
//zamena crvenog i plavog piksela BGR(A) -> RGB(A)
if (infoHeader.bitsPerPixel == 32)
{
for (int i = 0; i < infoHeader.width * infoHeader.height * infoHeader.bitsPerPixel / 8; i += 4)
{
uint8_t temp = this->pixels[i];
this->pixels[i] = this->pixels[i + 2];
this->pixels[i + 2] = temp;
}
}
else if (infoHeader.bitsPerPixel == 24)
{
for (int i = 0; i < infoHeader.width * infoHeader.height * infoHeader.bitsPerPixel / 8; i += 3)
{
uint8_t temp = this->pixels[i];
this->pixels[i] = this->pixels[i + 2];
this->pixels[i + 2] = temp;
}
}
Layer newLayer(this->height,this->width,this->bitsPerPixel,this->pixels);
if (image->numberOfLayers != 0)
image->resizeLayers(newLayer);
image->layers.push_back(newLayer);
image->numberOfLayers++;
input.close();
}
else {
throw std::runtime_error("Unable to open the input image file.");
}
}
}
void bmpFormat::read(std::string sourceFileName)
{
{
std::ifstream输入{sourceFileName,std::ios_base::binary};
如果(输入)
{
BMPFileHeader fileHeader;//结构实例
BMPInfoHeader infoHeader;//结构实例
BMPColorHeader colorHeader;//结构实例
uint32_t row_stein{0};
read((char*)&fileHeader,sizeof(fileHeader));
if(fileHeader.fileType!=BMPID){
抛出std::runtime_错误(“错误!无法识别的文件格式”);
}
read((char*)&infoHeader,sizeof(infoHeader));
this->bitsPerPixel=infoHeader.bitsPerPixel;
此->高度=infoHeader.height;
此->宽度=infoHeader.width;
如果(infoHeader.height<0)
抛出std::runtime_错误(“程序只能处理原点在左下角的BMP图像!”);
//跳转到像素数据位置
input.seekg(fileHeader.data\u offset,input.beg);
此->像素。调整大小(此->宽度*此->高度*此->位像素/8);
//这里我们检查是否需要考虑行填充
如果(infoHeader.width%4==0)
input.read((char*)this->pixels.data(),this->pixels.size());
否则{
row_stride=infoHeader.width*infoHeader.bitsPerPixel/8;
//uint32新的步幅=0;
uint32新的步幅=行步幅;
while(新的步幅%4!=0)
新的stride++;
std::矢量填充行(新的步幅-行步幅);
对于(int y=0;ypixels.data()+行步幅*y),行步幅);
input.read((char*)padding_row.data(),padding_row.size());
}
}
//扎梅纳·克里维诺一世普拉沃·皮克塞拉BGR(A)->RGB(A)
if(infoHeader.bitsPerPixel==32)
{
对于(int i=0;ipixels[i];
这个->像素[i]=这个->像素[i+2];
这个->像素[i+2]=temp;
}
}
else if(infoHeader.bitsPerPixel==24)
{
对于(int i=0;ipixels[i];
这个->像素[i]=这个->像素[i+2];
这个->像素[i+2]=temp;
}
}
图层新建图层(此->高度,此->宽度,此->位像素,此->像素);
如果(图像->层数!=0)
图像->缩放图层(新图层);
图像->图层。向后推(新建图层);
图像->numberOfLayers++;
input.close();
}
否则{
抛出std::runtime_错误(“无法打开输入图像文件”);
}
}
}
多亏了用户@camickr,我发现了这个问题。API不理解这种BMP格式(很可能是标题数据),所以我使用这个网站将BMP转换为BMP
结果很好。多亏了用户@camickr,我发现了这个问题。API不理解这种BMP格式(很可能是标题数据),所以我使用这个网站将BMP转换为BMP
它的效果很好。 C++的参与是切线的,所以我删除了标签。这是一个
void BMPFormater::read(std::string sourceFileName)
{
{
std::ifstream input{ sourceFileName, std::ios_base::binary };
if (input)
{
BMPFileHeader fileHeader; // struct instance
BMPInfoHeader infoHeader; // struct instance
BMPColorHeader colorHeader; // struct instance
uint32_t row_stride{ 0 };
input.read((char*)&fileHeader, sizeof(fileHeader));
if (fileHeader.fileType != BMPID) {
throw std::runtime_error("Error! Unrecognized file format.");
}
input.read((char*)&infoHeader, sizeof(infoHeader));
this->bitsPerPixel= infoHeader.bitsPerPixel;
this->height=infoHeader.height;
this->width=infoHeader.width;
if (infoHeader.height < 0)
throw std::runtime_error("The program can treat only BMP images with the origin in the bottom left corner!");
// Jump to the pixel data location
input.seekg(fileHeader.data_offset, input.beg);
this->pixels.resize(this->width * this->height * this->bitsPerPixel / 8);
// Here we check if there is a need to take into account row padding
if (infoHeader.width % 4 == 0)
input.read((char*)this->pixels.data(), this->pixels.size());
else {
row_stride = infoHeader.width * infoHeader.bitsPerPixel / 8;
// uint32_t new_stride = 0;
uint32_t new_stride = row_stride;
while (new_stride % 4 != 0)
new_stride++;
std::vector<uint8_t> padding_row(new_stride - row_stride);
for (int y = 0; y < infoHeader.height; ++y) { //cita red po red i svaki red peduje
input.read((char*)(this->pixels.data() + row_stride * y), row_stride);
input.read((char*)padding_row.data(), padding_row.size());
}
}
//zamena crvenog i plavog piksela BGR(A) -> RGB(A)
if (infoHeader.bitsPerPixel == 32)
{
for (int i = 0; i < infoHeader.width * infoHeader.height * infoHeader.bitsPerPixel / 8; i += 4)
{
uint8_t temp = this->pixels[i];
this->pixels[i] = this->pixels[i + 2];
this->pixels[i + 2] = temp;
}
}
else if (infoHeader.bitsPerPixel == 24)
{
for (int i = 0; i < infoHeader.width * infoHeader.height * infoHeader.bitsPerPixel / 8; i += 3)
{
uint8_t temp = this->pixels[i];
this->pixels[i] = this->pixels[i + 2];
this->pixels[i + 2] = temp;
}
}
Layer newLayer(this->height,this->width,this->bitsPerPixel,this->pixels);
if (image->numberOfLayers != 0)
image->resizeLayers(newLayer);
image->layers.push_back(newLayer);
image->numberOfLayers++;
input.close();
}
else {
throw std::runtime_error("Unable to open the input image file.");
}
}
}