Nickolay.info. Алгоритмы. Создаём файлы BMP на Си

В приведённом ниже листинге (процедурный Си) генерируются файлы в формате BMP 24 бита, например, такие:

Сгенерированный программой градиент

Листинг подробно закомментирован, в него включены также несколько альтернативных вариантов градиентов (функции Func, White2Black).

#include <stdio.h>
#include <malloc.h>
 
struct BitMapFile {
 int bfType;	 	//Метка BM
 long bfSize;           //Длина в байтах
 long Res;		//Резерв
 long bfOffs;		//Смещение области данных
 //Начало BITMAP_INFO:
 long biSize;		//Длина BITMAP_INFO
 long biWidth, biHeight;//Ширина и высота картинки
 int biPlanes;		//Число плоскостей
 int biBitCnt;		//Бит на пиксел
 long biCompr;		//Тип сжатия
 long biSizeIm;		//Размер изображения в байтах
 long biXPels,biYPels;	//Разрешение по горизонтали и вертикали
 long biClrUsed;	//Количество используемых цветов
 long biClrImp;		//Количество основных цветов
};
// Дальше идут байты в виде BB GG RR по строкам слева направо,
// но снизу вверх
 
void InitDefaults (BitMapFile *b) {
 b->bfType=0x4d42;
 b->Res=0;
 b->bfOffs=54;
 b->biSize=40;
 b->biPlanes=1;
 b->biBitCnt=24;
 b->biCompr=0;
 b->biXPels=4730; b->biYPels=4720;
 b->biClrUsed=0;  b->biClrImp=0;
}
 
void Func (char far *Img) {
 //От золотого FFCC00 до FFFFFF
 int i,j,k,all;
 char r,g,b;
 for (k=0; k<23; k++) { //Делаем одну строку:
  r=255; g=204; b=0; all=0;
  do {
   if (g<255) g++;
   for (j=0; j<5; j++) {
    if (b<255) b++;
    *Img++=b; *Img++=g; *Img++=r;
    all++;  if (all==512) goto END;
   }
  } while (1);
 END:
 }
}
 
 
/*
void Func (char far *Img) {
 //От FFFFCC до 000080, 16 строк, длина строки 512
 int i,j,k,all;
 char r,g,b;
for (k=0; k<23; k++) { //Делаем одну строку:
 r=256; g=256; b=204; all=0;
 do {
  r--; g--;
  for (j=0; j<2; j++) { *Img++=b; *Img++=g; *Img++=r;
   all++;  if (all==512) goto END;
  }
  r--; g--;
  for (j=0; j<2; j++) { *Img++=b; *Img++=g; *Img++=r; all++; if (all==512) goto END;}
  r--; g--;
  for (j=0; j<2; j++) { *Img++=b; *Img++=g; *Img++=r; all++; if (all==512) goto END;}
  b--;
 } while (1);
 END:
}
}
*/
 
/* void White2Black (char far *Img) {
 //Черный-синий-белый-синий-черный, размеры 1200 на 10
 int i,j,k;
 char r,g,b;
for (k=0; k<10; k++) {
 //Делаем одну строку:
 for (i=0; i<=255; i++) {
  b=i; g=0; r=0;
  *Img++=b; *Img++=g; *Img++=r;
 }
 for (i=0; i<=255; i++) {
  b=255; g=i; r=i;
  *Img++=b; *Img++=g; *Img++=r;
 }
 for (i=0; i<176; i++) {
  b=g=r=255;
  *Img++=b; *Img++=g; *Img++=r;
 }
 for (i=255; i>=0; i--) {
  b=255; g=i; r=i;
  *Img++=b; *Img++=g; *Img++=r;
 }
 for (i=255; i>=0; i--) {
  b=i; g=0; r=0;
  *Img++=b; *Img++=g; *Img++=r;
 }
}
} */
 
/* void White2Black (char far *Img) {
 //От белого через синий к черному, размеры д.б. 800 на 10
 int i,j,k;
 char r,g,b;
for (k=0; k<10; k++) {
 //Делаем 1 строку:
 for (j=0; j<240; j++) {
  b=g=r=255;
  *Img++=b; *Img++=g; *Img++=r;
 }
 for (i=255; i>=0; i--) {
  b=255; g=i; r=i;
  *Img++=b; *Img++=g; *Img++=r;
 }
 for (i=255; i>=0; i--) {
  b=i; g=0; r=0;
  *Img++=b; *Img++=g; *Img++=r;
 }
 for (j=0; j<48; j++) {
  b=g=r=0;
  *Img++=b; *Img++=g; *Img++=r;
 }
}
} */
 
int main (void) {
 FILE *w,*r;
 char far *Image;
 BitMapFile b;
 
 w=fopen ("!my.bmp","wb");
 if (w==NULL) {
  printf ("\n Can't open the file!");
  return 1;
 }
 
 InitDefaults (&b);
 //Выбираем размеры картинки!
 b.biWidth=512;
 b.biHeight=23;
 long Size= b.biWidth * b.biHeight * 3; //Размер изображения
 Image= (char far *) malloc (Size);
 // Добавляем длину заголовка
 Size+=54;
 b.bfSize=Size;
 
 //Здесь - вызов ф-ции White2Black или другой
 Func (Image);
 fwrite (&b,54,1,w);
 fwrite (Image,Size,1,w);
 fclose (w);
 return 0;
}

Вывод пишется в файл !my.bmp, графический режим для запуска не нужен.

Рейтинг@Mail.ru

вверх гостевая; E-mail