Официальный сайт студ.городка НГТУ
Программирование и БД » [C++] проблемы с редактированием bmp файла 

#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

#3  12.06.10 15:55

Re: [C++] проблемы с редактированием bmp файла

Revenger написал(а):

К чему iostream и std, если почти весь код в С-стиле?

)))
А у тебя тогда к чему new и delete, если весь код в С-стиле?

Offline

#4  12.06.10 16:17

Re: [C++] проблемы с редактированием bmp файла

Draloskop написал(а):

А у тебя тогда к чему new и delete, если весь код в С-стиле?

Revenger написал(а):

Код не очень, ибо писан был под специфичную задачу.

Offline

#5  15.06.10 10:51

Re: [C++] проблемы с редактированием bmp файла

Теперь у меня другой вопрос. С яркостью я разобрался, вроде нормально преобразует, но возникли проблемы с контрастностью. По какой формуле надо его расчитывать(вроде там должен быть какой то коэффициент)

Offline

#6  16.06.10 12:10

Re: [C++] проблемы с редактированием bmp файла

farid, а как ты с яркостью разобрался? в чем идея?

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

#8  16.06.10 13:51

Re: [C++] проблемы с редактированием bmp файла

farid, а почему unsigned? что это за тип?

Offline

#9  16.06.10 13:51

Re: [C++] проблемы с редактированием bmp файла

можешь еще этот кусок закоментить, хотя бы переменные для чего... а то не понятно...

Исправлено budka (16.06.10 14:05)

Offline

#10  16.06.10 17:36

Re: [C++] проблемы с редактированием bmp файла

Компьютер выдает информацию в двоичном коде. В обычных переменных старший бит отвечает за знак, в unsigned он не используется.

Offline

#11  16.06.10 18:01

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

farid написал(а):

В обычных переменных старший бит отвечает за знак, в unsigned он не используется.

выражение "обычные переменные" уже само по себе смешно. А вы поменяете одну "необычную переменную" на пять "обычных"?

И про неиспользуемый бит ты отжог.
данные в памяти не отличаются ничем, а вот в зависимости от типа первый бит будет знаковым, что важно только для конвертации в другой тип

Исправлено $up (16.06.10 18:04)

Offline

#12  16.06.10 19:42

Re: [C++] проблемы с редактированием bmp файла

$up написал(а):

А вы поменяете одну "необычную переменную" на пять "обычных"?

поменяю обычную на 3 вещественные.

Offline

#13  16.06.10 20:09

Re: [C++] проблемы с редактированием bmp файла

как мог так и обьяснил.
И вопрос тот же остался какую формулу надо применять для изменения контрастности?

Offline

#14  16.06.10 20:27

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

farid, если объяснить не можешь, значит сам до конца не понимаешь.

http://sources.ru/magazine/0805/paint.html

Offline

#15  16.06.10 22:21

Re: [C++] проблемы с редактированием bmp файла

$up, так как как насчет обмена переменных? Все еще меняешь?

Offline

#16  16.06.10 22:41

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

Revenger, меняю любые обычные переменные на переменную в xslt 8)

Offline

#17  17.06.10 00:46

Re: [C++] проблемы с редактированием bmp файла

$up, меня больше интересует обмен 4 переменных типа float на одну vector float - это осуществимо?

Исправлено Revenger (17.06.10 00:49)

Offline

#18  17.06.10 10:37

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

Revenger, я не совсем понимаю про что ты говоришь

float a,b,c,d;
vector float v = (vector float){a,b,c,d};

Offline

#19  17.06.10 12:39

Re: [C++] проблемы с редактированием bmp файла

$up, сколько за услуги по обмену целого массива возьмешь?

$up написал(а):

я не совсем понимаю про что ты говоришь

В смысле?

Offline

#20  17.06.10 13:36

Re: [C++] проблемы с редактированием bmp файла

а что в массиве в котором хранится растр нужно поменять, чтобы увеличить яркость?

Offline

#21  17.06.10 14:49

Re: [C++] проблемы с редактированием bmp файла

budka, просто прибавлять к каждому элементу, то значение на которое хочешь увеличить яркость и потом проверяй чтобы значение не превысило 255.

Offline

#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

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

budka, тебе буквы RGB о чём-нибудь говорят? Ты, вообще, представляешь за счёт чего яркость повышается или для тебя это чистая магия?

Offline

#24  17.06.10 15:41

Re: [C++] проблемы с редактированием bmp файла

$up, да понял уже, что палитру надо менять... только как?

Offline

#25  17.06.10 15:53

Re: [C++] проблемы с редактированием bmp файла

а изображение у тебя 24 битное?

Offline

#26  17.06.10 15:55

Re: [C++] проблемы с редактированием bmp файла

farid, 8 битное...

Offline

#27  17.06.10 16:00

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

budka написал(а):

да понял уже, что палитру надо менять...

у тебя GIF что ли?

Offline

#28  17.06.10 16:04

Re: [C++] проблемы с редактированием bmp файла

$up написал(а):

budka написал(а):

да понял уже, что палитру надо менять...

у тебя GIF что ли?

почему? обычное BMP 8 бит на пиксель...

Offline

#29  17.06.10 16:10

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

да, забыл что такие тоже бывают 8) Тогда да, тебе достаточно палитру поменять

Offline

#30  17.06.10 16:20

Re: [C++] проблемы с редактированием bmp файла

$up написал(а):

да, забыл что такие тоже бывают 8) Тогда да, тебе достаточно палитру поменять

только вот как это сделать понять не могу... можешь накинуть идею... я выше код скидывал, как палитру и растр записываю...

Offline

#31  17.06.10 16:42

$up
Профиль

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

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

проблема в твоей программе

Offline

#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

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

а ты уверен, что указатель в файле сейчас именно на палитре находится?
как ты записываешь файл?

Исправлено $up (18.06.10 12:34)

Offline

#37  18.06.10 17:33

Re: [C++] проблемы с редактированием bmp файла

$up написал(а):

а ты уверен, что указатель в файле сейчас именно на палитре находится?
как ты записываешь файл?

сделал... там palette это byte  и  проверке условия не работала...

теперь осталось контрастность сделать... там надо будет найти среднее между цветами и все что больше этого среднего - умножить на коэффициент, а что меньше - поделить... правильно говорю?

Offline

#38  18.06.10 21:02

Re: [C++] проблемы с редактированием bmp файла

как найти этот коэффициент?
для этого нужна же формула

Offline

#39  19.06.10 00:49

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

бери за среднее 159

по ссылке, которую я давал, есть пример изменения контраста, хотя можно и свой алгоритм придумать.

Offline

#40  19.06.10 12:13

Re: [C++] проблемы с редактированием bmp файла

$up написал(а):

бери за среднее 159

по ссылке, которую я давал, есть пример изменения контраста, хотя можно и свой алгоритм придумать.

по ссылке не понятно... ну вообщем брать за среднее 159 и все что больше умножать на коэффициент, а все что меньше делить, так?

Offline

#41  19.06.10 21:52

$up
Профиль

Re: [C++] проблемы с редактированием bmp файла

не совсем так, там коэффициент рассчитывается в зависимости от разности среднего и текущего цвета. Тебе нужно сжимать или растягивать диапазон яркости. т.е умножать на число больше единицы или на число меньше единицы.

Все цвета должны приближаться к серому 159 (снизу и сверху) при уменьшении контраста или растягиваться до 0 и 255, при увеличении

Исправлено $up (19.06.10 21:56)

Offline

#42  19.06.10 23:46

Re: [C++] проблемы с редактированием bmp файла

а как коэффициент расчитать? какая формула...???

Исправлено budka (20.06.10 20:01)

Offline

Программирование и БД » [C++] проблемы с редактированием bmp файла 

ФутЕр:)

© Hostel Web Group, 2002-2025.   Сообщить об ошибке

Сгенерировано за 0.270 сек.
Выполнено 14 запросов.