Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.11.2012, 17:12   #1
MartyM
 
Регистрация: 17.11.2012
Сообщений: 7
По умолчанию Работа с BMP -> JPEG

Здраствуйте, мне нужно написать конвертер изображений BMP -> JPEG на чистом Си, с использованием только стандартных функций (пишу на Pelles C). Вот в чём проблема:

1) Когда считываю BMP-файл, я вывожу все данные о файле на экран, но они немного криво показываются (например высота и ширина изображения), хотя я пользовался данными с википедии...

2) Я так понимаю чтобы мне перевести BMP в JPEG, нужно получить двумерный массив RGB значений (так мне сказали), для последующего перевода этих значений в JPEG. Значения RGB-палитры у меня есть, но я не знаю как правильно загнать их в двумерный массив.
Мне подсказывали, что надо записывать как-то так: "когда получишь двухмерный массив из [R,G,B] значений, его надо будет просто закодировать в жпег.
В шапке у тебя есть размеры рисунка Width х Height (Ширина х Высота, например 1024 х 768), есть одномерный массив array1d, ну а индексы по схеме.
array2d[i/Width][i%Width] = array1d[i]", но всё сводится к тому, что программа криво выдаёт Ширину и Высоту изображения.

Вообщем кто сможет чем-либо помочь - буду очень благодарен!

Код:
#include <stdio.h>
#include <string.h>
#include <locale.h>
// Структура BITMAP FILE HEADER 
typedef struct
{
unsigned char  b1, b2;   //Тип файла, Символы BM (смение 0, длина 2)
unsigned long  bfSize;   //Размер файла в байтах (Смещение 2, длина 4)
unsigned short bfReserved1;              //Бесполезно (Смещение 6, длина 2)
unsigned short bfReserved2;              //Бесполезно (Смещение 8, длина 2)
unsigned long bfOffBits;                  //Смещение до самого изображения (Смещение 10, длина 4)
} BmpHeader;
// Структура BITMAP INFO HEADER
typedef struct
{
unsigned long   biSize;                                           //Размер данной структуры в байтах. Опред. версия формата
unsigned long   biWidth;                                          //Ширина изображения в пикселях.
unsigned long   biHeight;                                        //Высота изображения в пикселях.
   unsigned short biPlanes;                                      //Количество цветовых плоскостей и в формате BMP содержит единицу.
   unsigned short biBitCount;                            //Количество бит на пиксель.
   unsigned short biCompression;                 //Тип сжатия для сжатых изображений
   unsigned short biSizeImage;                     //Размер изображения в байтах. Может содержать ноль для BI_RGB-изображений.
unsigned long   biXPelsPerMeter;          //Горизонтальное разрешение в пикселях на метр для целевого устройства.
unsigned long   biYPelsPerMeter;          //Вертикальное разрешение в пикселях на метр для целевого устройства.
   unsigned short biClrUsed;                              //Количество используемых цветовых индексов в палитре.
   unsigned short biClrImportant;                //Количество элементов палитры, необходимых для отображения изображения.
} BmpImageInfo;
// Структура палитры
typedef struct
  {
    unsigned char rgbBlue;
    unsigned char rgbGreen;
    unsigned char rgbRed;
    unsigned char rgbAlpha;
  } RGB;

int main()
{
setlocale(LC_ALL, "");
BmpHeader header;
                 BmpImageInfo info;
                 RGB *palette, *pixel;
int i = 0;
FILE *BmpInput, *BmpPalette;
if ((BmpInput = fopen("E:\\qwe.bmp", "rb")) == NULL)
  return -1;
if( !BmpInput )
  printf("Ошибка чтения BMP-файла.\n");
if ( fread (&header, sizeof(BmpHeader), 1, BmpInput) != 1 )
         printf("Ошибка.\n");

if ( fread (&info, sizeof(BmpImageInfo), 1, BmpInput) != 1 )
    printf("Ошибка.\n");

printf("_______Данные_о_BITMAP_INFO_HEADER_______\n");
printf("Размер структ. в байтах : %d bytes\n", info.biSize);
printf("Ширина изображения        : %d px\n", info.biWidth);
printf("Высота изображения        : %d px\n", info.biHeight);
printf("Кол. цветовых плоск.    : %d\n", info.biPlanes);
printf("Кол. бит на пиксель      : %d\n", info.biBitCount);
printf("Тип сжатия                        : %d\n", info.biCompression);
printf("Размер изобр. в байтах  : %d bytes\n", info.biSizeImage);
printf("Горизонт. разрешение    : %d px\n", info.biXPelsPerMeter);
printf("Вертикальное разрешение : %d px\n", info.biYPelsPerMeter);
printf("Кол. цветов. инд. в пал.: %d\n", info.biClrUsed);
printf("Кол. элементов палитры  : %d\n\n", info.biClrImportant);
// Считываем Цветовые индексы
if ( info.biSizeImage > 0 )
{
    palette = (RGB*)malloc(sizeof(RGB) *info.biSizeImage);
    if ( fread(palette, sizeof(RGB), info.biSizeImage, BmpInput) != info.biSizeImage )
}

// Записываем Цветовые индексы в файл
  BmpPalette = fopen("E://BmpMapColor.txt", "wr");
  if(!BmpPalette)
         printf("Ошибка.\n");
  for(int i=0; info.biSizeImage>i; i++)
  {
    pixel = &palette[i];
         if( fprintf(BmpPalette, "R:%d, G:%d, B:%d\n", pixel->rgbRed, pixel->rgbGreen, pixel->rgbBlue) < 0); //Записываем RGB значения в файл
  }
fclose(BmpInput);
fclose(BmpPalette);
return 0;
}
MartyM вне форума Ответить с цитированием
Старый 18.11.2012, 11:37   #2
Nuklon
Форумчанин
 
Аватар для Nuklon
 
Регистрация: 05.04.2012
Сообщений: 134
По умолчанию

Если проблемы возникают при загрузки битмапа, то что скажешь при написание кодера и декодера JPEG(sequential или progressive), можешь использовать библиотеку libjpeg.
Nuklon вне форума Ответить с цитированием
Старый 18.11.2012, 12:10   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Во первых, из за выравния (alingment), елементы структур могут не следовать одним за другим в памяти а во вторых сами переменные записаны в low endian а платформа на которох все это будет работать (вы не потрудились указать) может быть либо low endian либо big endian.
waleri вне форума Ответить с цитированием
Старый 18.11.2012, 12:13   #4
MartyM
 
Регистрация: 17.11.2012
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Nuklon Посмотреть сообщение
Если проблемы возникают при загрузки битмапа, то что скажешь при написание кодера и декодера JPEG(sequential или progressive), можешь использовать библиотеку libjpeg.
Я загружаю Битмап правильно, только все данные, которые выводятся смещены на один вниз, к примеру вместо Ширины картинки выводит ещё размер, а вместо высоты - ширину.
Можете посмотреть что не так? И если не сложно, помогите считать правильно RGB значения в двумерный массив.

Цитата:
Сообщение от waleri Посмотреть сообщение
Во первых, из за выравния (alingment), елементы структур могут не следовать одним за другим в памяти а во вторых сами переменные записаны в low endian а платформа на которох все это будет работать (вы не потрудились указать) может быть либо low endian либо big endian.
Если не сложно, могли бы вы рассказать про выравнивание по подробнее?
Насчёт переменных, я читал на википедии но ничего про low endian и big endian не нашёл, можете тоже объяснить?

Последний раз редактировалось Stilet; 18.11.2012 в 12:37.
MartyM вне форума Ответить с цитированием
Старый 18.11.2012, 12:30   #5
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Цитата:
Насчёт переменных, я читал на википедии но ничего про low endian и big endian не нашёл
Плохо искали. http://ru.wikipedia.org/wiki/Порядок_байтов
p51x вне форума Ответить с цитированием
Старый 18.11.2012, 12:42   #6
MartyM
 
Регистрация: 17.11.2012
Сообщений: 7
По умолчанию

А как сделать выравнивание?

Последний раз редактировалось MartyM; 18.11.2012 в 12:55.
MartyM вне форума Ответить с цитированием
Старый 18.11.2012, 14:07   #7
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от MartyM Посмотреть сообщение
А как сделать выравнивание?
Опцией компилятора. Или просто читать не структуру целиком а переменную за переменной.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по OpenGL и *.bmp/*.jpeg файлам. Vova777 Мультимедиа в Delphi 2 26.06.2011 09:31
Проблема с TImage, BMP, JPEG Florento Общие вопросы Delphi 5 16.06.2011 16:18
Ищу компонент конвертер(Bmp, Png, Tif, Gif...) в Jpeg ArtGrek Компоненты Delphi 16 25.05.2011 10:05
Как оптимизировать код перевода BMP в JPEG artemavd Общие вопросы Delphi 7 12.11.2010 12:18
Узнать цвет пикселя в Timage, если там не bmp а jpeg? TwiX Общие вопросы Delphi 4 27.09.2009 19:11