Java ImageIO正在读取RGB而不是ARGB数据

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

我正在为一个照片编辑器开发一个GUI,目前我正忙于从一个文件中加载一个32位BMP图像。在我开始尝试多层并将其成型为一层之前,一切都进展顺利。采用C++(exe文件)< /P>运行时类(图层造型和图像保存) 我使用pixelFormer软件制作了一个简单的300x300红色bmp图像,每个像素的值为R:255g:0b:0a:125

我注意到我下面的方法加载了一个RGB,其中alpha通道的默认值为255,其中125应该是。这是:

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++的参与是切线的,所以我删除了标签。这是一个 java < /C>问题,不是一个代码> C++ +/>代码>问题。但是,当我用C++阅读器加载这个相同的BMP文件时,即使C++标签保留了,这也不是足够的信息。你需要提到C++用来读取图像的库,因为在C++中没有“C++图像阅读器”类。也许从这里开始,看看您使用的库是否具有stock ImageIO所没有的功能。@PaulMcKenzie这不是一个库,而是我自己编写的一个类。它基本上是读取整个BMP,首先是标题,然后是实际像素值。请参阅:。没有给出解决方案,但给出了可能的解释,说明了为什么它不起作用。@kosingas…stock ImageIO没有的功能。-请看上面的链接。与C++代码的区别在于它是低级的,可以控制一切,而IMAIIO依赖于API来支持你正在尝试读取的格式。C++的参与是切线的,所以我删除了标签。这是一个 java < /C>问题,不是一个代码> C++ +/>代码>问题。但是,当我用C++阅读器加载这个相同的BMP文件时,即使C++标签保留了,这也不是足够的信息。你需要提到C++用来读取图像的库,因为在C++中没有“C++图像阅读器”类。也许从这里开始,看看您使用的库是否具有stock ImageIO所没有的功能。@PaulMcKenzie它不是一个库,而是一个类
    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.");
        }
    }
}