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

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

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

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

Q&A

解決済

2回答

2298閲覧

BMP画像の拡大と縮小

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2020/12/03 04:53

BMP画像を、任意にの数を入力して元の画像を拡大したいです。
一倍では画像の作成を出来るのですけど、二倍、三倍では、BMP画像が作成できません。
縮小は拡大とは別の処理が必要なのでしょうか。
必要なら教えていただけると幸いです。
拡大はどこが問題あるのか知りたいです。

c言語

1#include<stdio.h> 2#include<math.h> 3 4typedef unsigned char BYTE; 5 6//アライメント 7#pragma pack(push,1) 8typedef struct tagBITMAPFILEHEADER 9{ 10 unsigned short bfType; //ファイルタイプ 11 unsigned long bfSize; //ファイルサイズ (byte) 12 unsigned short bfReserved1; //予約領域 13 unsigned short bfReserved2; //予約領域 14 unsigned long bfOffBits; //予約領域 15} BITMAPFILEHEADER; 16#pragma pack(pop) 17 18typedef struct tagBITMAPINFOHEADER 19{ 20 unsigned long biSize; //情報ヘッダのサイズ (byte) 21 long biWidth; //画像の幅 (ピクセル) 22 long biHeight; //画像の高さ (ピクセル) 23 unsigned short biPlanes; //プレーン数 24 unsigned short biBitCount; //1 画素あたりのデータサイズ (bit) 25 unsigned long biCompression; //圧縮形式 26 unsigned long biSizeImage; //画像データ部のサイズ (byte) 27 long biXPixPerMeter; //横方向解像度 (1mあたりの画素数) 28 long biYPixPerMeter; //縦方向解像度 (1mあたりの画素数) 29 unsigned long biClrUsed; //格納されているパレット数 (使用色数) 30 unsigned long biClrImporant; //重要なパレットのインデックス 31} BITMAPINFOHEADER; 32 33typedef struct tagRGBQUAD 34{ 35 unsigned char rgbBlue; //青 36 unsigned char rgbGreen; //緑 37 unsigned char rgbRed; //赤 38 unsigned char rgbReserved; //予約領域 39} RGBQUAD; 40 41void main(int argc, char **argv) 42{ 43 BITMAPFILEHEADER BitMapFileHeader; //BMPのファイルヘッダー 44 BITMAPINFOHEADER BitMapInfoHeader; //BMPの情報ヘッダー 45 RGBQUAD BitMapColor; //カラーパレット 46 BYTE *pImg, *pChangeImg; 47 int i, j, k,l, m, iSize, sp1=0, sp2=0; 48 long lWidth, lHeight; 49 double dMult; 50 FILE *fp; 51 52 if(argc != 3) 53 { 54 printf("フォーマットが違います。"); 55 exit(1); 56 } 57 58 fp = fopen(argv[1],"rb"); 59 60 if(fp == NULL) 61 { 62 printf("ファイルが存在しません。"); 63 exit(1); 64 } 65 printf("%s file open\n", argv[1]); 66 67 //ファイルヘッダーを読み込む 68 fread(&BitMapFileHeader,sizeof(BITMAPFILEHEADER),1,fp); 69 if(BitMapFileHeader.bfType != 0x4D42){ 70 printf("ビットマップではありません。\n"); 71 exit(1); 72 } 73 74 //情報ヘッダーを読み込む 75 fread(&BitMapInfoHeader,sizeof(BITMAPINFOHEADER),1,fp); 76 77 //カラーパレットを読み込む 78 switch(BitMapInfoHeader.biBitCount) 79 { 80 case 8: 81 fread(&BitMapColor,sizeof(RGBQUAD),1,fp); 82 iSize = BitMapFileHeader.bfSize - ( 14 + 40 + 4 ); 83 printf("%d\n",BitMapInfoHeader.biBitCount); 84 break; 85 case 24: 86 iSize = BitMapFileHeader.bfSize - ( 14 + 40 ); 87 printf("%d\n",BitMapInfoHeader.biBitCount); 88 break; 89 case 32: 90 iSize = BitMapFileHeader.bfSize - ( 14 + 40 ); 91 printf("%d\n",BitMapInfoHeader.biBitCount); 92 break; 93 default: 94 printf("失敗しました"); 95 exit(1); 96 } 97 98 pImg = (BYTE *) malloc(iSize); 99 100 //画像データ部の読み込み 101 fread(pImg,sizeof(BYTE),iSize,fp); 102 103 //ファイルを閉じる 104 if(fclose(fp) == EOF){ 105 printf("ファイルを閉じることが出来ませんでした。\n"); 106 } 107 108 //パスのファイルへ書き込み 109 fp = fopen("sample.bmp","wb"); 110 111 //書き込み 112 dMult = atoi(argv[2]); 113 114 BitMapFileHeader.bfSize = BitMapFileHeader.bfSize + iSize*(dMult-1); 115 BitMapInfoHeader.biWidth *= dMult; 116 BitMapInfoHeader.biHeight *= dMult; 117 BitMapInfoHeader.biSizeImage *= dMult; 118 119 lWidth = BitMapInfoHeader.biWidth; 120 lHeight = BitMapInfoHeader.biHeight; 121 122 //拡大、縮小 の倍率 123 iSize *= dMult; 124 125 printf("倍率 %lf\n",dMult); 126 printf("width %d\n",lWidth); 127 printf("height %d\n",lHeight); 128 printf("Size %d\n",iSize); 129 130 printf("倍率 %lf\n",dMult); 131 printf("width %d\n",BitMapInfoHeader.biWidth); 132 printf("height %d\n",BitMapInfoHeader.biHeight); 133 printf("Size %d\n",BitMapFileHeader.bfSize); 134 printf("Size %d\n",BitMapInfoHeader.biSizeImage); 135 136 //ファイルヘッダーを書き込む 137 fwrite(&BitMapFileHeader,sizeof(BITMAPFILEHEADER),1,fp); 138 //情報ヘッダーを書き込む 139 fwrite(&BitMapInfoHeader,sizeof(BITMAPINFOHEADER),1,fp); 140 141 //マロック 142 pChangeImg = (BYTE *) malloc(iSize); 143 144 //画像データを書き込む 145 switch(BitMapInfoHeader.biBitCount) 146 { 147 //8bitのときを書き込む 148 case 8: 149 fwrite(&BitMapColor,sizeof(RGBQUAD),1,fp); 150 151 for(j=0; j<lHeight; j++) 152 { 153 for(m=0; m<dMult; m++) 154 { 155 for(i=0; i<lWidth; i++) 156 { 157 for(l=0; l<dMult; l++) 158 { 159 *(pChangeImg+sp2) = *(pImg+sp1); 160 sp1++; 161 sp2++; 162 } 163 sp1 = sp1-(dMult-1); 164 } 165 sp1 = sp1-lWidth*(dMult-1); 166 } 167 } 168 break; 169 //24bitのときを書き込む 170 case 24: 171 for(j=0; j<lHeight; j++) 172 { 173 for(i=0; i<lWidth; i++) 174 { 175 for(k=0; k<3; k++) 176 { 177 *(pChangeImg+sp2) = *(pImg+sp1); 178 sp1++; 179 sp2++; 180 } 181 } 182 } 183 break; 184 //32bitのときを書き込む 185 case 32: 186 for(i=0; i<lHeight; i++) 187 { 188 for(j=0; j<lWidth; j++) 189 { 190 for(k=0; k<4; k++) 191 { 192 *(pChangeImg+sp2) = *(pImg+sp1); 193 sp1++; 194 sp2++; 195 } 196 } 197 } 198 break; 199 } 200 201 //画像データ部を書き込む 202 fwrite(pChangeImg,sizeof(BYTE),iSize ,fp); 203 204 //ファイルを閉じる 205 fclose(fp); 206} 207

利用環境 Visual Studio 2019

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

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

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

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

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

guest

回答2

0

ベストアンサー

前も言いましたが、まずはBMPのデータ形式をしっかり調べましょう。
そこから、画像のX方向、Y方向の各ピクセルのデータ配置がわかりますんで、まずはそれをしっかり把握しましょう。
それが理解できれば、整数倍の拡大は簡単にできるでしょう

投稿2020/12/03 06:15

y_waiwai

総合スコア88042

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

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

退会済みユーザー

退会済みユーザー

2020/12/04 03:11

それがわかってもBMPファイルがうまく書き込めなくて困っています。
退会済みユーザー

退会済みユーザー

2020/12/04 03:16

他のペイントソフトで拡大して保存したBMPとファイルサイズやヘッダを比較検証してみれば、違いが分かると思いますよ
退会済みユーザー

退会済みユーザー

2020/12/04 03:24

そもそも保存することができないです。 一倍だと実行を出来るんですけど、二倍以上にすると一文字も読み込めません。 ヘッダーのみで行うと数字はあっています。
退会済みユーザー

退会済みユーザー

2020/12/04 05:04 編集

まあ既に私が回答した通り画像サイズの算出方法がおかしいし、そのサイズを元にmallocで確保してバッファ以上にループ回してるからまともに動かないでしょうね。 変換以前に、最後のswitch文の所を丸ごとコメントアウトして、拡大後のサイズのBMPを出力して他のソフトで読めるようにする所から始めた方がよいでしょう。(memsetで適当な数値で画像データを埋めると判り易いかも) 一度に全部やろうとせず、コツコツと段階踏んでハードルをクリアしてください。どこまで正しく動いているか把握できない状態では、検証もデバッグもままなりません。
guest

0

細かくは見てないですが、パっと見て画像サイズ(BitMapInfoHeader.biSizeImage)の算出方法が間違っています。
我流でやる前に、まずは既存の拡大縮小処理のサンプルを参考にしてみた方がよいでしょう。

ニアレストネイバー

投稿2020/12/03 05:13

編集2020/12/03 05:15
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問