すみません;;
このプログラムを何とか「画像を縮小して表示」に直していただけないでしょうか?
画像サイズは800×480でbmpです。
何ビットか飛ばして読み込めば?だかなんだか言われて色々試してみましたが、ズームみたいになったり、画像の一部だけ表示されたりと、まったくうまくいきませんでした。
縮小した画像は保存ではなくただ表示したいだけです。
Ubuntuでやってます。
よろしくお願いします。
C
1#include <stdio.h> 2#include <stdlib.h> 3#include <fcntl.h> 4#include <sys/mman.h> 5#include <string.h> 6 7#define SCREENWIDTH 800 8#define SCREENHEIGHT 480 9#define BYTES_PER_PIXCEL 4 10#define SCREENSIZE (SCREENWIDTH * SCREENHEIGHT * BYTES_PER_PIXCEL) 11#define RGB888(r, g, b) (((r) & 0xff) << 16 | \ 12 ((g) & 0xff) << 8 | \ 13 ((b) & 0xff)) 14 15typedef struct tagBITMAPFILEHEADER{ // ビットマップファイルヘッダ 16 unsigned short bfType; // 識別子0x4d42(‘B’,‘M’) 17 unsigned long bfSize; // ファイルサイズ 18 unsigned short bfReserved1; // 使わない 19 unsigned short bfReserved2; // 使わない 20 unsigned long bfOffBits; // ファイル内の画像データ開始位置 21} __attribute__((packed)) BITMAPFILEHEADER; 22 23typedef struct tagBITMAPINFOHEADER{ // ビットマップ情報ヘッダ 24 unsigned long biSize; // 情報ヘッダサイズ 25 long biWidth; // 画像の幅 26 long biHeight; // 画像の高さ 27 unsigned short biPlanes; // プレーン数(1に固定) 28 unsigned short biBitCount; // 1ピクセルあたりのビット数 29 unsigned long biCompression; // 圧縮タイプ 30 unsigned long biSizeImage; // 画像データサイズ 31 long biXPixPerMeter; // 横1mあたりのピクセル数 32 long biYPixPerMeter; // 縦1mあたりのピクセル数 33 unsigned long biClrUsed; // パレット数 34 unsigned long biClrImporant; // 重要パレット数 35} __attribute__((packed)) BITMAPINFOHEADER; 36 37/* 38 * draw_bmp - draw bitmap image on LCD screen 39 * pfb: pointer to the framebuffer 40 * x0: x coordinates of image 41 * y0: y coordinates of image 42 * w: image width 43 * h: image height 44 * bmpdata: pointer to the image data 45 */ 46void draw_bmp(unsigned int *pfb, int x0, int y0, int w, int h, unsigned char *bmpdata) 47{ 48 int x1 = x0 + w; 49 int y1 = y0 + h; 50 int padding = (w * 3) % 4; 51 int c = 0; 52 unsigned char r, g, b; 53 int x, y; 54 55 // 開始位置から画像を表示します。 56 // 最も下のラインから始まり、 57 // 最も上のラインに向かって1ラインずつ画像データを格納します。 58 for(y = y1 - 1; y >= y0; y--){ 59 for(x = x0; x < x1; x++){ 60 // 1pixelから、R,G,B各色のカラーデータを取得します。 61 b = bmpdata[c++]; 62 g = bmpdata[c++]; 63 r = bmpdata[c++]; 64 // LCDにカラーデータを表示します。 65 pfb[y * SCREENWIDTH + x] = RGB888(r, g, b); 66 } 67 68 //1ラインのデータサイズが4の倍数にならない時は、 69 //4の倍数になるようにラインデータの末尾に1つ以上の0を付加します。 70 c += padding; 71 } 72} 73 74int main(void) { 75 int fd_in, fd_fb; 76 unsigned int *pfb; 77 unsigned char *bmpdata; 78 int datasize; 79 int x, y; 80 81 struct bmpheader_t{ 82 BITMAPFILEHEADER fh; 83 BITMAPINFOHEADER ih; 84 } bmp; 85 86 87 // 引数に設定されたファイルをオープンします。 88 // オープンに失敗した場合はエラーで終了します。 89 if ((fd_in = open("hana.bmp", O_RDONLY)) < 0) { 90 perror("open(file)"); 91 return 1; 92 } 93 94 // ビットマップヘッダに、画像データを読み込みます。 95 // 読み込みに失敗した場合はエラーで終了します。 96 if (read(fd_in, &bmp, sizeof(bmp)) != sizeof(bmp)){ 97 perror("read(file)"); 98 return 1; 99 } 100 101 // 取得した画像データより、 102 // 識別子、1ピクセルあたりのビット数、圧縮タイプ、画像の高さをチェックします。 103 if (bmp.fh.bfType != 0x4d42 || bmp.ih.biBitCount != 24 104 || bmp.ih.biCompression != 0 || bmp.ih.biHeight < 0){ 105 fprintf(stderr, "unsupported bitmap format\n"); 106 return 1; 107 } 108 109 // 取得した画像データより、 110 // 画像データの幅と高さが画面サイズよりも大きい場合はエラーで終了します。 111 if (bmp.ih.biWidth > SCREENWIDTH || bmp.ih.biHeight > SCREENHEIGHT){ 112 fprintf(stderr, "image size too big\n"); 113 return 1; 114 } 115 116 // 画像データから、ビットマップファイルのヘッダ情報のデータサイズを引いた値を 117 // データサイズとして、メモリ領域を確保します。 118 datasize = bmp.fh.bfSize - sizeof(bmp); 119 // 必要なメモリ領域を確保できない場合はエラーで終了します。 120 if (!(bmpdata = malloc(datasize))){ 121 perror("malloc"); 122 return 1; 123 } 124 125 // 確保したメモリ領域に画像データを読み込みます。 126 // 読み込みに失敗した場合はエラーで終了します。 127 if (read(fd_in, bmpdata, datasize) != datasize){ 128 perror("read(file)"); 129 free(bmpdata); 130 return 1; 131 } 132 133 //画像ファイルをクローズします。 134 close(fd_in); 135 136 // フレームバッファをオープンします。 137 // オープンに失敗した場合はエラーで終了します。 138 if ((fd_fb = open("/dev/fb0", O_RDWR)) < 0) { 139 perror("open(fb)"); 140 free(bmpdata); 141 return 1; 142 } 143 144 // mmapによりバッファの先頭アドレスを取得します。 145 pfb = mmap(0, SCREENSIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd_fb, 0); 146 // 取得に失敗した場合はエラーで終了します。 147 if (pfb == MAP_FAILED){ 148 perror("mmap"); 149 free(bmpdata); 150 return 1; 151 } 152 153 // LCDの画面表示を全て消去するために、 154 // 取得したアドレスから確保領域を0で初期化します。 155 memset(pfb, 0, SCREENSIZE); 156 157 // 画像がLCDの中央に表示されるようにx, yを設定します。 158 x = (SCREENWIDTH - bmp.ih.biWidth) / 2; 159 y = (SCREENHEIGHT - bmp.ih.biHeight) / 2; 160 161 // LCDに画像を表示します。 162 draw_bmp(pfb, x, y, bmp.ih.biWidth, bmp.ih.biHeight, bmpdata); 163 164 // フレームバッファのために確保した領域を開放します。 165 munmap(pfb, SCREENSIZE); 166 // フレームバッファをクローズします。 167 close(fd_fb); 168 // 画像表示に必要なメモリ領域を開放します。 169 free(bmpdata); 170 171 return 0; 172} 173
提示されたプログラムはどなたか他の方の書いたものでしょうか。そうであれば、プログラムの出所 (書籍なら著者名・書名・ページ数、ウェブならURL) を教えて下さい。
回答2件
あなたの回答
tips
プレビュー