Answer the question
In order to leave comments, you need to log in
How to properly convert an image to 1-bit?
I want to convert from 24 bit to 1-bit, i.e. to have only 2 colors - white and black.
That is, first you need to create a palette of 2 colors - black and white, and then for each pixel determine which of these two colors it belongs to.
I did the palette and pixel translation - I even tried it in two ways -
through grayscale and through the average brightness of a pixel, but for 1 bit images it doesn't seem to matter.
The problem is not in this - but in how I can record the image after all these tricky manipulations.
That is, if I understood everything correctly, only palette indexes are stored in such a black and white image - that is, in my case 1 or 0 .
But after three RGB values, there is also a value for transparency, where 0 is usually stored.
i.e. if my palette is
00 00 00 00 FF FF FF 00
and the first pixel is white - then its index is 1, and if black - then 0,
i.e. how I thought it should look -
for (int i=0;i<BMInfoHeader.Height;i++)
for (int j=0;j<BMInfoHeader.Width;j++)
{
if (currbit>=7)//собрали байт
{
fwrite(&one_byte,1,1,f);//записали его
one_byte=0;//обнулили его
currbit=0;//обнулили счетчик для сдвига
}
if (Rgbtriple[i][j].Blue>100) //если больше опред. значения
{
one_byte|=(1<<currbit);//записываем 1
currbit++;
}
else currbit++;//иначе - 0 (т.е просто сдвигаем вправо)
}
fwrite(&one_byte,1,1,f);//дописываю последний байт
fclose(f);
int Image::loadimage(char *filename)
{
FILE *f;
int imageIdx=0; //image index counter
fopen_s(&f,filename,"rb");//открываем файл
if (f == NULL) return 0;//если не смогли открыть - вызвращаем код ошибки - 0
fread(&BMFileHeader, sizeof(BMFileHeader),1,f);//считали заголовок
if (BMFileHeader.Type !=0x4D42)//проверили - точно ли формат .bmp
{
fclose(f);
return 0;
}
fread(&BMInfoHeader, sizeof(BMInfoHeader),1,f); //считали информацию об изображении
//this->info();//вывели информацию
if (BMInfoHeader.BitCount == 1 || BMInfoHeader.BitCount==4 || BMInfoHeader.BitCount==8)//проверка на палитровое изображение
{
loadpaletteimg(f);
return 0;
}
fseek(f, BMFileHeader.OffsetBits, SEEK_SET); //переместили указатель в нужное место
if (BMInfoHeader.BitCount==24)
{
Rgbtriple=new RGBTRIPLE*[BMInfoHeader.Height];
Rgbquad=0;
for (int i = 0; i < BMInfoHeader.Height; i++)//построчно
{
Rgbtriple[i]=new RGBTRIPLE[BMInfoHeader.Width];
fread(Rgbtriple[i], sizeof(RGBTRIPLE), BMInfoHeader.Width, f);
}
if(Rgbtriple) cout<<"Изображение успешно загружено!"<<endl;
}
if (BMInfoHeader.BitCount==16)
{
Rgbquad=new RGBQUAD*[BMInfoHeader.Height];
Rgbtriple=0;
for (int i = 0; i < BMInfoHeader.Height; i++)//построчно
{
Rgbquad[i]=new RGBQUAD[BMInfoHeader.Width];
fread(Rgbquad[i], sizeof(RGBQUAD), BMInfoHeader.Width, f);
}
if(Rgbquad) cout<<"Изображение успешно загружено!"<<endl;
}
else return 0;
fclose(f);
return 1;
}
byte one_byte=0;
int currbit=0;
byte mask=0X80;
for (int i=0;i<BMInfoHeader.Height;i++)
for (int j=0;j<BMInfoHeader.Width;j++)
{
if (currbit>=8)//собрали байт
{
fwrite(&one_byte,1,1,f);//записали его
one_byte=0;
currbit=0;
}
if (Rgbtriple[i][j].Blue>100)
{
one_byte|=(mask>>currbit);
currbit++;
}
else currbit++;
}
fwrite(&one_byte,1,1,f);//дописываю последний байт
fclose(f);
}
Answer the question
In order to leave comments, you need to log in
First, currbit>=7 should be replaced with currbit>=8, but that doesn't seem to be the problem.
It's hard to tell right away what the problem is, since both the file reading procedure and the source file itself are also involved here.
There is another point - the string must be a multiple of 4 bytes.
Plus, the bits are filled not from left to right, but from right to left, that is, currbit should run values not 0..7, but 7..0.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question