#1 11.06.10 22:31
[C++] проблемы с редактированием bmp файла
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
struct tagBITMAPFILEHEADER
{
short bfType[2];
long bfSize[1];
short bfReserved1;
short bfReserved2;
long bfOffbits;
};
struct tagBITMAPINFOHEADER
{
long biSize;
long biWidth;
long biHeight;
short biPlanes;
short biBitCount;
long biCompression;
long biSizeImage;
long biXPelsPerMeter;
long biYPelPerMeter;
long biClrUsed;
long biClrImportant;
};
struct RGBQUAD
{
short rgbBlue;
short rgbGreen;
short rgbRed;
short rgbResrved;
};
void ggg(FILE *fl,long pos,int pro,int height,int weight)
{
int amountPoint=height*weight;
char RGB;
fseek(fl,pos,SEEK_SET);
for(int i=0;i<amountPoint;i++)
{
char R=0;
char G=0;
char B=0;
fread((void*)&R,1,1,fl);
R+=(char)pro;
if(R>255) R=255;
fseek(fl,-1,SEEK_CUR);
fwrite((void*)&R,1,1,fl);
R=0;
fread((void*)&G,1,1,fl);
G+=(char)pro;
if(G>255) G=255;
fseek(fl,-1,SEEK_CUR);
fwrite((void*)&G,1,1,fl);
G=0;
fread((void*)&B,1,1,fl);
B+=(char)pro;
if(B>255) B=255;
fseek(fl,-1,SEEK_CUR);
fwrite((void*)&B,1,1,fl);
B=0;
}
}
void main(){
FILE *bmpImage;
RGBQUAD A;
tagBITMAPFILEHEADER BMFH;
tagBITMAPINFOHEADER BMIH;
if((bmpImage=fopen("1.bmp","rb+"))==NULL) return;
//-------------------------------------------------------
for(int i=0;i!=2;i++)
{
fread((void*)&BMFH.bfType[i],1,1,bmpImage);
//fwrite((void*)&BMFH.bfType[i],1,1,bmpCreature);
}
printf("BM signature: ");
for(int i=0;i!=2;i++)
printf("%c",BMFH.bfType[i]);
printf("\n");
//-------------------------------------------------------
for(int i=0;i!=1;i++)
{
fread((void*)&BMFH.bfSize[i],4,1,bmpImage);
//fwrite((void*)&BMFH.bfSize[i],4,1,bmpCreature);
}
printf("File size: ");
for(int i=0;i!=1;i++)
printf("%d",BMFH.bfSize[i]);
printf(" bytes\n");
fread((void*)&BMFH.bfReserved1,2,1,bmpImage);
//fwrite((void*)&BMFH.bfReserved1,2,1,bmpCreature);
printf("Reserved1 %d\n",BMFH.bfReserved1);
fread((void*)&BMFH.bfReserved2,2,1,bmpImage);
//fwrite((void*)&BMFH.bfReserved2,2,1,bmpCreature);
printf("Reserved2: %d\n",BMFH.bfReserved2);
fread((void*)&BMFH.bfOffbits,4,1,bmpImage);
//fwrite((void*)&BMFH.bfOffbits,4,1,bmpCreature);
printf("Location of bitmap data: %hd bytes\n\n",BMFH.bfOffbits);
//-------------------------------------------------------
fread((void*)&BMIH.biSize,4,1,bmpImage);
//fwrite((void*)&BMIH.biSize,4,1,bmpCreature);
printf("Size of information header: %d bytes\n",BMIH.biSize);
fread((void*)&BMIH.biWidth,4,1,bmpImage);
//fwrite((void*)&BMIH.biWidth,4,1,bmpCreature);
printf("Image width: %d pixels\n",BMIH.biWidth);
fread((void*)&BMIH.biHeight,4,1,bmpImage);
//fwrite((void*)&BMIH.biHeight,4,1,bmpCreature);
printf("Image height: %d pixels\n",BMIH.biHeight);
fread((void*)&BMIH.biPlanes,2,1,bmpImage);
//fwrite((void*)&BMIH.biPlanes,2,1,bmpCreature);
printf("Number of color planes: %d\n",BMIH.biPlanes);
fread((void*)&BMIH.biBitCount,2,1,bmpImage);
//fwrite((void*)&BMIH.biBitCount,2,1,bmpCreature);
printf("Number of bits per pixel: %d\n",BMIH.biBitCount);
fread((void*)&BMIH.biCompression,4,1,bmpImage);
//fwrite((void*)&BMIH.biCompression,2,1,bmpCreature);
printf("Compression method used: %d\n",BMIH.biCompression);
fread((void*)&BMIH.biSizeImage,4,1,bmpImage);
//fwrite((void*)&BMIH.biSizeImage,4,1,bmpCreature);
printf("Number of bytes of bitmap data: %d\n",BMIH.biSizeImage);
fread((void*)&BMIH.biXPelsPerMeter,4,1,bmpImage);
//fwrite((void*)&BMIH.biXPelsPerMeter,4,1,bmpCreature);
printf("Horizontal screen resolution: %d pixels/meter\n",BMIH.biXPelsPerMeter);
fread((void*)&BMIH.biYPelPerMeter,4,1,bmpImage);
//fwrite((void*)&BMIH.biYPelPerMeter,4,1,bmpCreature);
printf("Vertical screen resolution: %d pixels/meter\n",BMIH.biYPelPerMeter);
fread((void*)&BMIH.biClrUsed,4,1,bmpImage);
//fwrite((void*)&BMIH.biClrUsed,4,1,bmpCreature);
printf("Number of colors used in the image: %d\n",BMIH.biClrUsed);
fread((void*)&BMIH.biClrImportant,4,1,bmpImage);
//fwrite((void*)&BMIH.biClrImportant,4,1,bmpCreature);
printf("Number of important colors : %d\n",BMIH.biClrImportant);
ggg(bmpImage,54,1,1024,768);
fclose(bmpImage);
}
При написании курсовика столкнулся с такой проблемой. В задании надо менять яркость изображения. Я открываю его как бинарный фаил и пытаюсь изменить каждый бит, который отвечает соответственно за синию, зеленую и красную составляющую. Конкретно сейчас картинка заливается равномерным серым цветом. В Hex Editore показано, что корректно изменились только первый и второй бит одного пикселя, дальше идет копирование содержание второго бита до конца файла.(пытаюсь поменять на 1)
До обработки:
42 4D 36 00 24 00 00 00 00 00 36 00 00 00 28 00 00 00 00 04
00 00 00 03 00 00 01 00 18 00 00 00 00 00 00 00 24 00 13 0B
00 00 13 0B 00 00 00 00 00 00 00 00 00 00 12 40 58 16 44 5C
1E 4D 68 21 5 0 6B 1D 4F 6B 1E 50 6C 1A 4E 6C 1F 53 71 1D 50 .......
После обработки:
42 4D 36 00 24 00 00 00 00 00 36 00 00 00 28 00 00 00 00 04
00 00 00 03 00 00 01 00 18 00 00 00 00 00 00 00 24 00 13 0B
00 00 13 0B 00 00 00 00 00 00 00 00 00 00 13 41 41 41 41 41
41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ......
Изображение 24 битное, т.е. на каждый бит приходится одна компонента цвета.
Помогите пожалуйста, где я ошибся?
Исправлено farid (11.06.10 22:32)
Offline
#2 11.06.10 23:58
Re: [C++] проблемы с редактированием bmp файла
farid написал(а):
Помогите пожалуйста, где я ошибся?
А не судьба было из файла сразу структуру читать? А то по полям - создается впечатление, что месье знает толк в извращениях.
К чему iostream и std, если почти весь код в С-стиле?
Вот код для чтения BMP-шки
Код: cpp:
#include <string.h> struct FileHeader { short bfType; //тип файла (для битового образа - BM) long bfSize; //размер файла в dword short bfReserved1; //не используется short bfReserved2; //не используется long bfOffbits; //смещение данных битового образа от заголовка в байтах }bmp_head; struct MapInfo { long Size; //число байт, занимаемых структурой InfoHeader long Width; //ширина битового образа в пикселях long Height; //высота битового образа в пикселях short Planes; //число битовых плоскостей устройства short BitCount; //число битов на пиксель long Compression; //тип сжатия long SizeImage; //размер картинки в байтах long XPelsPerMeter;//горизонтальное разрешение устройства, пиксель/м long YPelPerMeter; //вертикальное разрешение устройства, пиксель/м long ClrUsed; //число используемых цветов long ClrImportant; //число "важных" цветов } bmp_MapInfo; unsigned char palitra[256][4]; void main() { FILE *FileBMPTC; char nameBMPTC[40]; //имя исходного файла strcpy(nameBMPTC,"ALienShooter.bmp"); FileBMPTC=fopen(nameBMPTC,"rb"); //открываем файл fread(&bmp_head,sizeof(bmp_head),1,FileBMPTC); //считываем заголовок BMP файла fread(&bmp_MapInfo,sizeof(bmp_MapInfo),1,FileBMPTC); //считываем MAPINFO if(!bmp_MapInfo.SizeImage) bmp_MapInfo.SizeImage=bmp_head.bfSize-sizeof(bmp_head)-sizeof(bmp_MapInfo); int BytesPerLine=bmp_MapInfo.SizeImage/bmp_MapInfo.Height; //количество байт на линию int ActivePixels=bmp_MapInfo.Width*bmp_MapInfo.BitCount/8; //число отображаемых пикселов if(!bmp_MapInfo.SizeImage) //если параметр SizeImage определен(указан размер картинки в байтах) { BytesPerLine=bmp_MapInfo.Width*bmp_MapInfo.BitCount/8; //количество байт на линию if(BytesPerLine%4) //выравнивание по 32 битам BytesPerLine+=(4-BytesPerLine%4); } unsigned char *buffer; //буфер под строку buffer=new unsigned char[BytesPerLine]; for(int i=bmp_MapInfo.Height-1;i>=0;i--) { fread(buffer,sizeof(unsigned char),BytesPerLine,FileBMPTC); //читаем строку for(int j=0;j<ActivePixels;j+=3) //перебираем по 3 байта { А вот здесь уже вставляй свою обработку пиксела. } А вот тут записывай полученную строку изображения. } delete []buffer; //освобождаем память fclose(FileBMPTC); //закрываем файл }
Код не очень, ибо писан был под специфичную задачу.
Исправлено Revenger (12.06.10 01:59)
Offline
#7 16.06.10 13:46
Re: [C++] проблемы с редактированием bmp файла
У меня переменная, куда я сохранял значение байта, была типом char. А надо было unsigned char.
unsigned char RedactBrightness(unsigned int C,unsigned int edit)
{
C+=((C/100)*edit); //тут непостредственно изменяется яркость. EDIT вводится с клавитуры (т.е. на сколько изменять яркость)
if(C<0) C=0; //контролируем чтобы не выходило за рамки цвета
if(C>255) C=255;
return (unsigned char)C;
}
void RedactBmp(unsigned int Brightness,unsigned int Contrast,unsigned char *image,int size)
{
char buf;
for(int i=0;i<size;i+=3)
{
image[i]=RedactBrightness(image[i],Brightness);
image[i+1]=RedactBrightness(image[i+1],Brightness);
image[i+2]=RedactBrightness(image[i+2],Brightness);
// редактируем каждый байт
}
}
Исправлено farid (16.06.10 17:35)
Offline
#10 16.06.10 17:36
#11 16.06.10 18:01
Re: [C++] проблемы с редактированием bmp файла
farid написал(а):
В обычных переменных старший бит отвечает за знак, в unsigned он не используется.
выражение "обычные переменные" уже само по себе смешно. А вы поменяете одну "необычную переменную" на пять "обычных"?
И про неиспользуемый бит ты отжог.
данные в памяти не отличаются ничем, а вот в зависимости от типа первый бит будет знаковым, что важно только для конвертации в другой тип
Исправлено $up (16.06.10 18:04)
Offline
#12 16.06.10 19:42
#13 16.06.10 20:09
#14 16.06.10 20:27
Re: [C++] проблемы с редактированием bmp файла
farid, если объяснить не можешь, значит сам до конца не понимаешь.
http://sources.ru/magazine/0805/paint.html
Offline
#15 16.06.10 22:21
#16 16.06.10 22:41
#17 17.06.10 00:46
#18 17.06.10 10:37
#19 17.06.10 12:39
#20 17.06.10 13:36
#21 17.06.10 14:49
#22 17.06.10 15:07
Re: [C++] проблемы с редактированием bmp файла
farid, у меня идет запись палитры отдельно и самого растра отдельно:
Код::
palette = new RGBQUAD[256];
fread(palette, sizeof(RGBQUAD), 256, bmpfile);
rastr = new char*[BMPV5header.bV5Height];
fseek(bmpfile, BMPfileheader.bfOffBits, SEEK_SET);
for (int i = BMPV5header.bV5Height - 1; ; i--)
{
if (i >= 0 )
{
rastr[i] = new char[BMPV5header.bV5Width];
fread(rastr[i], 1, BMPV5header.bV5Width, bmpfile);
fread(&empty, 1, ((3*BMPV5header.bV5Width)%4), bmpfile);
}
else break;
}значит потом я должен увеличить значения rastr[i][j], чтобы увеличить яркость ?
вот так:
Код::
for (int i = 0; i < BMPV5header.bV5Height; i++)
for (int j = 0; j < BMPV5header.bV5Width; j++)
{
rastr[i][j] = rastr[i][j] + 3;
}Offline
#23 17.06.10 15:36
#24 17.06.10 15:41
#25 17.06.10 15:53
#26 17.06.10 15:55
#27 17.06.10 16:00
#28 17.06.10 16:04
#29 17.06.10 16:10
#30 17.06.10 16:20
#31 17.06.10 16:42
Re: [C++] проблемы с редактированием bmp файла
что тут накидывать, очевидно же.
palette[i].rgbBlue = (palette[i].rgbBlue < 255) ? palette[i].rgbBlue+1: 255;
palette[i].rgbGreen = (palette[i].rgbGreen < 255) ? palette[i].rgbGreen+1: 255;
palette[i].rgbRed = (palette[i].rgbRed < 255) ? palette[i].rgbRed+1: 255;
Offline
#32 17.06.10 17:04
Re: [C++] проблемы с редактированием bmp файла
$up написал(а):
что тут накидывать, очевидно же.
palette[i].rgbBlue = (palette[i].rgbBlue < 255) ? palette[i].rgbBlue+1: 255;
palette[i].rgbGreen = (palette[i].rgbGreen < 255) ? palette[i].rgbGreen+1: 255;
palette[i].rgbRed = (palette[i].rgbRed < 255) ? palette[i].rgbRed+1: 255;
он почему то не яркость увеличивает, а размазывает...
Offline
#33 17.06.10 20:06
Re: [C++] проблемы с редактированием bmp файла
пишу вот так и яркость не увеличивается:
Код::
palette[i].rgbRed = palette[i].rgbRed + 5;
palette[i].rgbBlue = palette[i].rgbBlue + 5;
palette[i].rgbGreen = palette[i].rgbGreen + 5;
if (palette[i].rgbRed > 255)
palette[i].rgbRed = 255;
if (palette[i].rgbBlue > 255)
palette[i].rgbBlue = 0;
if (palette[i].rgbGreen > 255)
palette[i].rgbGreen = 0;в чем проблема?
Исправлено budka (17.06.10 20:07)
Offline
#34 18.06.10 08:49
#35 18.06.10 10:16
Re: [C++] проблемы с редактированием bmp файла
$up написал(а):
проблема в твоей программе
а что может быть не правильно? считываю палитру и раст вот так:
Код::
palette = new RGBQUAD[256];
fread(palette, sizeof(RGBQUAD), 256, bmpfile);
rastr = new unsigned char*[BMPV5header.bV5Height];
fseek(bmpfile, BMPfileheader.bfOffBits, SEEK_SET);
for (int i = BMPV5header.bV5Height - 1; ; i--)
{
if (i >= 0 )
{
rastr[i] = new unsigned char[BMPV5header.bV5Width];
fread(rastr[i], 1, BMPV5header.bV5Width, bmpfile);
fread(&empty, 1, ((3*BMPV5header.bV5Width)%4), bmpfile);
}
else break;
}Offline
#36 18.06.10 12:24
#37 18.06.10 17:33
Re: [C++] проблемы с редактированием bmp файла
$up написал(а):
а ты уверен, что указатель в файле сейчас именно на палитре находится?
как ты записываешь файл?
сделал... там palette это byte и проверке условия не работала...
теперь осталось контрастность сделать... там надо будет найти среднее между цветами и все что больше этого среднего - умножить на коэффициент, а что меньше - поделить... правильно говорю?
Offline
#38 18.06.10 21:02
#39 19.06.10 00:49
#40 19.06.10 12:13
Re: [C++] проблемы с редактированием bmp файла
$up написал(а):
бери за среднее 159
по ссылке, которую я давал, есть пример изменения контраста, хотя можно и свой алгоритм придумать.
по ссылке не понятно... ну вообщем брать за среднее 159 и все что больше умножать на коэффициент, а все что меньше делить, так?
Offline
#41 19.06.10 21:52
Re: [C++] проблемы с редактированием bmp файла
не совсем так, там коэффициент рассчитывается в зависимости от разности среднего и текущего цвета. Тебе нужно сжимать или растягивать диапазон яркости. т.е умножать на число больше единицы или на число меньше единицы.
Все цвета должны приближаться к серому 159 (снизу и сверху) при уменьшении контраста или растягиваться до 0 и 255, при увеличении
Исправлено $up (19.06.10 21:56)
Offline

