質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

2486閲覧

C言語での画像の縮小について2

shuppi

総合スコア47

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/12/02 00:34

編集2016/12/02 01:51

またまた画像の縮小で躓いてしまいました。
UbuntuでArmadilloを使って作っています。
hana.bmpという800×480の画像を縮小表示するプログラムです。

今載せているのは、800×480のLCDにhana.bmpを自分が決めたサイズで横に3枚、縦に2枚ただ並べるだけのものです。
うまくいった!と思ったら、上下反転して出てきてしまいました。

たぶん、下から読み込んで、表示する時に上から描画されているから上下反転になるのではないかと思い、自分で探してみましたが、どこがおかしいか全く気が付きませんでした。

C

1(y = h - 1; y >= 0; y -= 3)

C

1(y = 0; y < h; y += 3)

に変えれば?と思い、変えてみましたが、やはり上下反転のままでした。

どこがおかしいのでしょうか。教えていただきたいです。プログラムでお願いします。

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MasahikoHirata

2016/12/02 01:26

LCDの設定に’上下反転’のオプションがありませんか?まず小さな映像を試しに作成してLCDに表示させてみて、これが上下反転表示されるか?を試されたらいかがでしょうか?
guest

回答1

0

ベストアンサー

こんにちは。

ループの中の処理を見ると、y行のデータをy行へ出力しているように見えます。
それですと、yを回す方向を逆にしても結果は同じと思います。
データを出力する側を修正すればうまくと思います。

現在> pfb[(y * 13 / 40 + y0) * SCREENWIDTH + (x * 13 / 40 + x0)] = RGB888(r, g, b);
修正> pfb[(h-1-(y * 13 / 40 + y0)) * SCREENWIDTH + (x * 13 / 40 + x0)] = RGB888(r, g, b);

投稿2016/12/02 02:26

編集2016/12/02 02:27
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shuppi

2016/12/02 02:30

ありがとうございます!とても助かりました!
majiponi

2016/12/02 10:28

以前、私が教えた式に間違いがあったせいですな…すまぬ。 r = bmpdata[x * 3 + y * (w * 3 + padding) + 2]; 本当は、yじゃなくて(h-1-y)が正しかったです。ビットマップファイルがボトムアップなのを忘れていました。出力側か入力側のどちらかを合わせてあげればokです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問