Конвертер из Bmp в Tga - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток. Возникла проблема с конвертером изображений (Bmp->Tga). Дело в том, что изображение, получившееся в результате кодирования, наклонено вбок (можете удостовериться сами, запустив программу). Третьи сутки борюсь с этой проблемой, совсем отчаялся, прошу помощи. Уж не покиньте, пожалуйста Вот код (пока написал исключительно для преобразования 24-битного бмп в несжатый тга):
Листинг программы
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <locale.h>
  4. #include "stdlib.h"
  5. #include "math.h"
  6.  
  7. // Структура BITMAP FILE HEADER ---------------------------------------------------------------------------------------------------------
  8. #pragma pack(push)
  9. #pragma pack(1)
  10. typedef struct
  11. { unsigned char b1, b2;
  12. unsigned long bfSize; //Размер файла в байтах (Смещение 2, длина 4)
  13. unsigned short bfReserved1; //Бесполезно (Смещение 6, длина 2)
  14. unsigned short bfReserved2; //Бесполезно (Смещение 8, длина 2)
  15. unsigned long bfOffBits; //Смещение до самого изображения (Смещение 10, длина 4)
  16. } BmpHeader;
  17. #pragma pack(pop)
  18. // Структура BITMAP INFO HEADER ---------------------------------------------------------------------------------------------------------
  19. typedef struct
  20. {
  21. unsigned long biSize; //Размер данной структуры в байтах. Опред. версия формата
  22. unsigned long biWidth; //Ширина изображения в пикселях.
  23. unsigned long biHeight; //Высота изображения в пикселях.
  24. unsigned short biPlanes; //Количество цветовых плоскостей и в формате BMP содержит единицу.
  25. unsigned short biBitCount; //Количество бит на пиксель.
  26. unsigned short biCompression; //Тип сжатия для сжатых изображений
  27. unsigned short biSizeImage; //Размер изображения в байтах. Может содержать ноль для BI_RGB-изображений.
  28. unsigned long biXPelsPerMeter; //Горизонтальное разрешение в пикселях на метр для целевого устройства.
  29. unsigned long biYPelsPerMeter; //Вертикальное разрешение в пикселях на метр для целевого устройства.
  30. unsigned short biClrUsed; //Количество используемых цветовых индексов в палитре.
  31. unsigned short biClrImportant; //Количество элементов палитры, необходимых для отображения изображения.
  32. } BmpImageInfo;
  33. // Структура TGA INFO HEADER ---------------------------------------------------------------------------------------------------------
  34. typedef struct {
  35. char idlength;
  36. char colourmaptype;
  37. char datatypecode;
  38. short int colourmaporigin;
  39. short int colourmaplength;
  40. char colourmapdepth;
  41. short int x_origin;
  42. short int y_origin;
  43. short width;
  44. short height;
  45. char bitsperpixel;
  46. char imagedescriptor;
  47. } TgaImageInfo;
  48. typedef struct {
  49. unsigned char r;
  50. unsigned char g;
  51. unsigned char b;
  52. // unsigned char a;
  53. } RGB;
  54. void MergeBytes(RGB *,unsigned char *,int);
  55. int main(int argc, char *argv[])
  56. {
  57. int n=0, i,j;
  58. BmpHeader bmpheader;
  59. BmpImageInfo bmpimageinfo;
  60. TgaImageInfo tgaimageinfo;
  61. RGB *pixels, *outpixels;
  62. unsigned char tmp[5];
  63. //int massR[i][j], massG[i][j], massB[i][j];
  64. int pad, size;
  65. int bytes2read;
  66. FILE *BmpImage = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/example.bmp","rb");
  67. FILE *BmpCode = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/BmpCode.txt","w");
  68. FILE *TgaCode = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/TgaCode.txt","w");
  69. FILE *TgaImage = fopen("E:/Jazblki programmirovanija/Kursovaya_Revchenko_10-IT-3/TgaImage.tga","wb");
  70. setlocale(LC_ALL, "");
  71. if (!BmpImage ) {
  72. printf("Ошибка чтения BMP-файла.\n");
  73. return 1;
  74. }
  75. //Выравнивание структуры--------------------------------------------------
  76. pad = sizeof(BmpHeader);
  77. printf("BmpHeader до выравнивания: %d\n", pad);
  78. if (pad > 14)
  79. {
  80. while (pad != 14)
  81. {
  82. pad -= 1;
  83. }
  84. }
  85. printf("BmpHeader после выравнивания: %d\n", pad);
  86. //---------------------------------------------------------------------------------------
  87. if (fread(&bmpheader, pad, 1, BmpImage) != 1){
  88. printf("Ошибка чтения заголовка Bmp-изображения\n");
  89. return 2;
  90. }
  91. if (fread (&bmpimageinfo, sizeof(BmpImageInfo), 1, BmpImage) != 1 ){
  92. printf("Ошибка чтения информации Bmp-изображения.\n");
  93. return 3;
  94. }
  95. printf("sizeof(BmpImageInfo) = %d\n", sizeof(BmpImageInfo));
  96. printf("_______Данные_о_BITMAP_FILE_HEADER_______\n");
  97. printf("Тип файла : %c%c\n", bmpheader.b1, bmpheader.b2);
  98. printf("Размер файла : %d bytes\n", bmpheader.bfSize);
  99. printf("Резервный слот 1 : %d\n", bmpheader.bfReserved1);
  100. printf("Резервный слот 2 : %d\n", bmpheader.bfReserved2);
  101. printf("Смешение до изображения : %d bytes\n\n", bmpheader.bfOffBits);
  102. printf("_______Данные_о_BITMAP_INFO_HEADER_______\n");
  103. printf("Размер структ. в байтах : %d bytes\n", bmpimageinfo.biSize);
  104. printf("Ширина изображения : %d px\n", bmpimageinfo.biWidth);
  105. printf("Высота изображения : %d px\n", bmpimageinfo.biHeight);
  106. printf("Кол. цветовых плоск. : %d\n", bmpimageinfo.biPlanes);
  107. printf("Кол. бит на пиксель : %d-bit\n", bmpimageinfo.biBitCount);
  108. printf("Тип сжатия : %d\n", bmpimageinfo.biCompression);
  109. bmpimageinfo.biSizeImage = bmpimageinfo.biXPelsPerMeter;
  110. bmpimageinfo.biXPelsPerMeter = bmpimageinfo.biYPelsPerMeter;
  111. bmpimageinfo.biYPelsPerMeter = bmpimageinfo.biClrUsed;
  112. bmpimageinfo.biClrUsed = 0;
  113. printf("Размер изобр. в байтах : %d bytes\n", bmpimageinfo.biSizeImage);
  114. printf("Горизонт. разрешение : %d px\n", bmpimageinfo.biXPelsPerMeter);
  115. printf("Вертикальное разрешение : %d px\n", bmpimageinfo.biYPelsPerMeter);
  116. printf("Кол. цветов. инд. в пал.: %d\n", bmpimageinfo.biClrUsed);
  117. printf("Кол. элементов палитры : %d\n\n", bmpimageinfo.biClrImportant);
  118. size = bmpimageinfo.biHeight * bmpimageinfo.biWidth;
  119. printf("size * sizeof(RGB) = %d\n", size * sizeof(RGB));
  120. if ((pixels = malloc(size * sizeof(RGB))) == NULL){
  121. printf("Malloc error\n");
  122. }
  123. for (int i=0;i<size;i++) {
  124. pixels[i].r = 0;
  125. pixels[i].g = 0;
  126. pixels[i].b = 0;
  127. //pixels[i].a = 0;
  128. }
  129. // Считываем Цветовые индексы-------------------------------------------------------------------------------------------------------------------
  130. fseek(BmpImage, bmpheader.bfOffBits, 0); //смещение на bmpheader.bfOffBits = 54 символа (пропускаем данные о BmpHeader и BmpImageInfo)
  131. bytes2read = bmpimageinfo.biBitCount / 8;
  132. if (bmpimageinfo.biBitCount == 24){
  133. printf("Считывание\n");
  134. if(size > 0){
  135. for (int i=0; i<size; i++)
  136. {
  137. fread(tmp, 1, bytes2read, BmpImage);
  138. MergeBytes(&(pixels[i]),tmp,bytes2read);
  139. }
  140. printf("Цветовые индексы считаны\n");
  141. for(int i=0; i<size; i++){
  142. fprintf(BmpCode,"%d %d %d\n",pixels[i].r, pixels[i].g, pixels[i].b);
  143. //printf("%d\n",i);
  144. //if((pixels[i].r==0)&&(pixels[i].g==0)&&(pixels[i].b==0)) { printf("%d\n",i); return 10;}
  145. //tmp[0] = pixels[i].r;
  146. //tmp[1] = pixels[i].g;
  147. //tmp[2] = pixels[i].b;
  148. //printf("%d %d %d\n",tmp[0],tmp[1],tmp[2]);
  149. //MergeBytes(&(outpixels[i]),tmp,bytes2read);
  150. fprintf(TgaCode, "%d %d %d\n", pixels[i].r, pixels[i].g, pixels[i].b);
  151. }
  152. }
  153. }
  154. putc(0,TgaImage);
  155. putc(0,TgaImage);
  156. putc(2,TgaImage); /* uncompressed RGB */
  157. putc(0,TgaImage); putc(0,TgaImage);
  158. putc(0,TgaImage); putc(0,TgaImage);
  159. putc(0,TgaImage);
  160. putc(0,TgaImage); putc(0,TgaImage); /* X origin */
  161. putc(0,TgaImage); putc(0,TgaImage); /* y origin */
  162. putc((bmpimageinfo.biWidth & 0x00FF),TgaImage);
  163. putc((bmpimageinfo.biWidth & 0xFF00) / 256,TgaImage);
  164. putc((bmpimageinfo.biHeight & 0x00FF),TgaImage);
  165. putc((bmpimageinfo.biHeight & 0xFF00) / 256,TgaImage);
  166. putc(24,TgaImage); /* 24 bit bitmap */
  167. putc(0,TgaImage);
  168. for (int i=0;i<size;i++) {
  169. putc(pixels[i].b,TgaImage);
  170. putc(pixels[i].g,TgaImage);
  171. putc(pixels[i].r,TgaImage);
  172. //putc(pixels[i].a,TgaImage);
  173. }
  174. fclose(BmpImage);
  175. fclose(BmpCode);
  176. fclose(TgaImage);
  177. fclose(TgaCode);
  178. return 0;
  179. }
  180.  
  181. void MergeBytes(RGB *pixel,unsigned char *p,int bytes)
  182. {
  183. if (bytes == 4) {
  184. pixel->r = p[2];
  185. pixel->g = p[1];
  186. pixel->b = p[0];
  187. //pixel->a = p[3];
  188. } else if (bytes == 3) {
  189. pixel->r = p[2];
  190. pixel->g = p[1];
  191. pixel->b = p[0];
  192. //pixel->a = 0;
  193. } else if (bytes == 2) {
  194. pixel->r = (p[1] & 0x7c) << 1;
  195. pixel->g = ((p[1] & 0x03) << 6) | ((p[0] & 0xe0) >> 2);
  196. pixel->b = (p[0] & 0x1f) << 3;
  197. //pixel->a = (p[1] & 0x80);
  198. }
  199. }

Решение задачи: «Конвертер из Bmp в Tga»

textual
Листинг программы
  1. //....
  2. int sz = (size*bytes2read)+56; //размер
  3. putc(sz,BmpImage); putc(0,BmpImage); putc(0,BmpImage); putc(0,BmpImage);
  4. //....

Объяснение кода листинга программы

  1. В первой строке кода объявлена переменная sz, которая вычисляет размер изображения в байтах, учитывая размер изображения и количество байтов, которые необходимо прочитать.
  2. Затем происходит запись значения переменной sz в файл BmpImage.
  3. После этого записываются 4 дополнительных байта со значением 0 в файл BmpImage.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4.333 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут