プログラミングでの画像の生成について

このQ&Aのポイント
  • プログラミングで画像の生成を行う際に、明るさの調整や色の変換をするプログラムを作成する方法についての質問です。
  • 具体的には、画像の輝度値を使って明るさを調整したり、色相を変えたりする方法について知りたいと思っています。
  • また、プログラム内でのビットマップ画像の扱い方や、ファイルの読み込みと保存についても教えていただけると助かります。
回答を見る
  • ベストアンサー

プログラミングでの画像の生成について・・・・・・・・

任意の画像をfと呼び,座標(x,y)における画像fの輝度値を(R(x,y),G(x,y),B(x,y))と呼ぶことにします。 以下の処理を行うプログラムを作成してください。 1,画像fの明るさがm分の1になった画像h1(x,y)=(R(x,y)/m,G(x,y)/m,B(x,y)/m)を生成する。 ここで,mは0<m<10の範囲にある任意の整数である. 2,画像fから法256の画像h2(x,y)=((n×R(x,y))mod(256),(n×G(x,y))mod(256),(n×B(x,y))mod(256))を生成する。 ここで,nは任意の正の整数である. *printfとscanfを使用するためにインクルードする*/ #include<stdio.h> /*ビットマップ画像を扱うためのヘッダ*/ #include<Dll_BMP_C.h> //画像ファイル名最大長(バイト) #define NAME_SIZE 101 int main(void) { int j,k; /* nWidth:画像の幅、nHeight:画像の高さ、nVal:輝度値*/ int nWidth,nHeight; /*pcFileName:画像ファイル名を保存する配列*/ char pcFileName[NAME_SIZE]; /*pBmpOrig:読み込んだ画像へのポインタ pBmpCopy:複製した画像へのポインタ*/ DllBmp*pBmpOrig,*pBmpCopy; /*読み込む画像のファイル名を指定する*/ printf(“読み込む画像”); scanf(“%s”,pcFileName); /*画像を読み込みメモリに保存する 読み込みに失敗したら実行を中止する*/ pBmpOrig=DllBmpReadImage(pcFileName); if(pBmpOrig==NULL) { printf(“画像の読み込みに失敗! 実行を中止します\n”); exit(1); } /*読み込んだ画像のヘッダ情報を表示する*/ DllBmpShowHeader(pBmpOrig); /*読み込んだ画像の大きさを得る*/ nWidth=DllBmpGetWidth(pBmpOrig); nHeight= DllBmpGetHeight (pBmpOrig); /* 画像を生成する */ for(j = 0; j < nHeight; j++) for(k = 0; k < nWidth; k++) { DllBmpSetPixelValueR(pBmpOrig, j, k, 255); DllBmpSetPixelValueG(pBmpOrig, j, k, 255); DllBmpSetPixelValueB(pBmpOrig, j, k, 255); } /*保存する画像のファイル名を指定する*/ printf(“保存する画像”); scanf(“%s”,pcFileName); /*画像を保存する 保存に失敗したら実行を中止する*/ if(!DllBmpWriteImage(pcFileName,pBmpOrig)); { printf(“画像の保存に失敗! 実行に中止します”); exit(1); } /*画像をメモリから消去する*/ DllBmpDleteImage(pBmpOrig); return 0; } 剰余は%演算子を使って求めることができると思うのですが・・・。。 処理内容を選択できて、mとnの値を指定できるように作りたいのですが・・・・・ 何かアドバイス的なものをすみませんがよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

あくまでアドバイスです(過信しないでください)。 /* 画像fの明るさがm分の1になった画像h1(x,y)=(R(x,y)/m,G(x,y)/m,B(x,y)/m)を生成する。 */ static void DoH1(DllBmp* pBmpOrig, int m) { int r = 0; int g = 0; int b = 0; /*なるべく変更してはまずいものにはconstを付けます*/ const int nWidth = DllBmpGetWidth(pBmpOrig); const int nHeight= DllBmpGetHeight(pBmpOrig); /*0<m<10を実行(今回は中でする)*/ if(m < 0)m = 0; if(m >= 10)m = 10; /* 画像を生成する */ for(j = 0; j < nHeight; j++) for(k = 0; k < nWidth; k++) { /*色彩の輝度を取り出す*/ r = DllBmpGetPixelValueR(pBmpOrig, j, k); g = DllBmpGetPixelValueG(pBmpOrig, j, k); b = DllBmpGetPixelValueB(pBmpOrig, j, k);     /*輝度の設定*/ DllBmpSetPixelValueR(pBmpOrig, j, k, r / m); DllBmpSetPixelValueG(pBmpOrig, j, k, g / m); DllBmpSetPixelValueB(pBmpOrig, j, k, b / m); } } /* 画像fから法256の画像h2(x,y)=((n×R(x,y))mod(256),(n×G(x,y))mod(256),(n×B(x,y))mod(256))を生成する。 */ static void DoH2(DllBmp* pBmpOrig, int n) { int r = 0; int g = 0; int b = 0; /*なるべく変更してはまずいものにはconstを付けます*/ const int nMod = 256; const int nWidth = DllBmpGetWidth(pBmpOrig); const int nHeight= DllBmpGetHeight(pBmpOrig); /* 画像を生成する */ for(j = 0; j < nHeight; j++) for(k = 0; k < nWidth; k++) { /*色彩の輝度を取り出す*/ r = DllBmpGetPixelValueR(pBmpOrig, j, k); g = DllBmpGetPixelValueG(pBmpOrig, j, k); b = DllBmpGetPixelValueB(pBmpOrig, j, k);     /*輝度の設定*/ DllBmpSetPixelValueR(pBmpOrig, j, k, (n * r) % nMod); DllBmpSetPixelValueG(pBmpOrig, j, k, (n * g) % nMod); DllBmpSetPixelValueB(pBmpOrig, j, k, (n * b) % nMod); } } 長くなってきているので関数に置いています。そうした方が、改良や修正取り扱いが楽になります。 キーボードから受け取ったデータを渡して以下のどちらかを呼び出します。 /*キーボードから入力を受け付ける*/ m = get???(); /* 画像を生成する */ DoH1(pBmpOrig, m); または DoH2(pBmpOrig, m); を呼び出す

fantazical
質問者

お礼

ほんとうにありがとうございます。 すごく助かりました。

関連するQ&A

  • 画像の輝度値のプログラムについて・・・・・・

    プログラムをPCでやる前にある程度、何かに書いてからやっているのですが、画像の1部分の色を変えたいのですが、例えば画像の左半分を黒くした画像を生成したい場合は,(一般的には,輝度値は0~255までの整数(8ビット)か,または0~65535までの整数(16ビット)により表される) *printfとscanfを使用するためにインクルードする*/ #include<stdio.h> /*ビットマップ画像を扱うためのヘッダ*/ #include<Dll_BMP_C.h> //画像ファイル名最大長(バイト) #define NAME_SIZE 101 int main(void) { int j,k; /* nWidth:画像の幅、nHeight:画像の高さ、nVal:輝度値*/ int nWidth,nHeight; /*pcFileName:画像ファイル名を保存する配列*/ char pcFileName[NAME_SIZE]; /*pBmpOrig:読み込んだ画像へのポインタ pBmpCopy:複製した画像へのポインタ*/ DllBmp*pBmpOrig,*pBmpCopy; /*読み込む画像のファイル名を指定する*/ printf(“読み込む画像”); scanf(“%s”,pcFileName); /*画像を読み込みメモリに保存する 読み込みに失敗したら実行を中止する*/ pBmpOrig=DllBmpReadImage(pcFileName); if(pBmpOrig==NULL) { printf(“画像の読み込みに失敗! 実行を中止します\n”); exit(1); } /*読み込んだ画像のヘッダ情報を表示する*/ DllBmpShowHeader(pBmpOrig); /*読み込んだ画像の大きさを得る*/ nWidth=DllBmpGetWidth(pBmpOrig); nHeight= DllBmpGetHeight (pBmpOrig); /* 画像を生成する */  for(j = 0; j < nHeight; j++)   for(k = 0; k < nWidth; k++)    {     DllBmpSetPixelValueR(pBmpOrig, j, k, 255);     DllBmpSetPixelValueG(pBmpOrig, j, k, 255);     DllBmpSetPixelValueB(pBmpOrig, j, k, 255);    } /*保存する画像のファイル名を指定する*/ printf(“保存する画像”); scanf(“%s”,pcFileName); /*画像を保存する 保存に失敗したら実行を中止する*/ if(!DllBmpWriteImage(pcFileName,pBmpOrig)); { printf(“画像の保存に失敗! 実行に中止します”); exit(1); } /*画像をメモリから消去する*/ DllBmpDleteImage(pBmpOrig); return 0; } 画像の輝度値を操作するプログラムをやっているのですが、画像の左半分を黒くした画像を生成する場合は、 DllBmpSetPixelValueR(pBmpOrig, j, k, 255); DllBmpSetPixelValueG(pBmpOrig, j, k, 255); DllBmpSetPixelValueB(pBmpOrig, j, k, 255); の部分のRが赤、Gが緑、Bが青なんですが、その値をすべて0にすればいいんでしょうか?もしくはあらたに条件式を作るべきなのでしょうか??そして画像の左半分を黒くしたい場合は、 for(j = 0; j < nHeight; j++)   for(k = 0; k < nWidth; k++) の部分のj < nHeightをj < nHeight/2にしたらなるでしょうか?? この場合だと上半分になってしまうでしょうか?? PCがまだ使えないのでルーズリーフにいろいろ試行錯誤して書いてるのですが、他に何かヒントがあればよろしくお願いします。。。。。 すみませんがお願いします。

  • プログラムをやっているのですが・・・・・

    C言語についての質問です。 画像の左半分を黒くした画像を生成したいのですが・・・・・・・ /*printfとscanfを使用するためにインクルードする*/ #include<stdio.h> /*ビットマップ画像を扱うためのヘッダ*/ #include<Dll_BMP_C.h> //画像ファイル名最大長(バイト) #define NAME_SIZE 101 int main(void) { int j,k; /* nWidth:画像の幅、nHeight:画像の高さ、nVal:輝度値*/ int nWidth,nHeight; /*pcFileName:画像ファイル名を保存する配列*/ char pcFileName[NAME_SIZE]; /*pBmpOrig:読み込んだ画像へのポインタ pBmpCopy:複製した画像へのポインタ*/ DllBmp*pBmpOrig,*pBmpCopy; /*読み込む画像のファイル名を指定する*/ printf(“読み込む画像”); scanf(“%s”,pcFileName); /*画像を読み込みメモリに保存する 読み込みに失敗したら実行を中止する*/ pBmpOrig=DllBmpReadImage(pcFileName); if(pBmpOrig==NULL) { printf(“画像の読み込みに失敗! 実行を中止します\n”); exit(1); } /*読み込んだ画像のヘッダ情報を表示する*/ DllBmpShowHeader(pBmpOrig); /*読み込んだ画像の大きさを得る*/ nWidth=DllBmpGetWidth(pBmpOrig); nHeight= DllBmpGetHeight (pBmpOrig); /* 画像を生成する */ for(j = 0; j < nHeight; j++) for(k = 0; k < nWidth; k++) { DllBmpSetPixelValueR(pBmpOrig, j, k, 255); DllBmpSetPixelValueG(pBmpOrig, j, k, 255); DllBmpSetPixelValueB(pBmpOrig, j, k, 255); } /*保存する画像のファイル名を指定する*/ printf(“保存する画像”); scanf(“%s”,pcFileName); /*画像を保存する 保存に失敗したら実行を中止する*/ if(!DllBmpWriteImage(pcFileName,pBmpOrig)); { printf(“画像の保存に失敗! 実行に中止します”); exit(1); } /*画像をメモリから消去する*/ DllBmpDleteImage(pBmpOrig); return 0; } 画像の輝度値を操作するプログラムをやっているのですが、画像の左半分を黒くした画像を生成する場合は、 DllBmpSetPixelValueR(pBmpOrig, j, k, 255); DllBmpSetPixelValueG(pBmpOrig, j, k, 255); DllBmpSetPixelValueB(pBmpOrig, j, k, 255); の部分のRが赤、Gが緑、Bが青なんですが、その値をすべて0にすればいいんでしょうか?もしくはあらたに定義したり、条件式を作るべきなのでしょうか?? 左半分を変色したい場合はnWidth/2と変えれば大丈夫だと思います。 すみませんがお願いします。 わかる方は、教えてください。よろしくお願いします。

  • プログラムを紙に書いていろいろやっているのですがで分からないところがあります・・・・・・・・・・・・・・

    /*printfとscanfを使用するためにインクルードする*/ #include<stdio.h> /*ビットマップ画像を扱うためのヘッダ*/ #include<Dll_BMP_C.h> //画像ファイル名最大長(バイト) #define NAME_SIZE 101 int main(void) { int j,k; /* nWidth:画像の幅、nHeight:画像の高さ、nVal:輝度値*/ int nWidth,nHeight; /*pcFileName:画像ファイル名を保存する配列*/ char pcFileName[NAME_SIZE]; /*pBmpOrig:読み込んだ画像へのポインタ pBmpCopy:複製した画像へのポインタ*/ DllBmp*pBmpOrig,*pBmpCopy; /*読み込む画像のファイル名を指定する*/ printf(“読み込む画像”); scanf(“%s”,pcFileName); /*画像を読み込みメモリに保存する 読み込みに失敗したら実行を中止する*/ pBmpOrig=DllBmpReadImage(pcFileName); if(pBmpOrig==NULL) { printf(“画像の読み込みに失敗! 実行を中止します\n”); exit(1); } /*読み込んだ画像のヘッダ情報を表示する*/ DllBmpShowHeader(pBmpOrig); /*読み込んだ画像の大きさを得る*/ nWidth=DllBmpGetWidth(pBmpOrig); nHeight= DllBmpGetHeight (pBmpOrig); /* x座標とy座標の値を足すと奇数になるすべてのピクセルを白(RGB成分の輝度値が255)にする画像を生成する */  for(j = 0; j < nHeight; j++)   for(k = 0; k < nWidth; k++)   if(j+k%2==1)     {     DllBmpSetPixelValueR(pBmpOrig, j, k, 255);     DllBmpSetPixelValueG(pBmpOrig, j, k, 255);     DllBmpSetPixelValueB(pBmpOrig, j, k, 255);    } /*保存する画像のファイル名を指定する*/ printf(“保存する画像”); scanf(“%s”,pcFileName); /*画像を保存する 保存に失敗したら実行を中止する*/ if(!DllBmpWriteImage(pcFileName,pBmpOrig)); { printf(“画像の保存に失敗! 実行に中止します”); exit(1); } /*画像をメモリから消去する*/ DllBmpDleteImage(pBmpOrig); return 0; } 画像の輝度値を操作するプログラムをやっているのですが、x座標とy座標の値を足すと奇数になるすべてのピクセルを白(RGB成分の輝度値が255)にする画像を生成したいのですが、こんな感じで作ってみたんですが、条件式はif(j+k%2==1) で作ってみたんですが、これだとj+kよりk%2の方がやっぱり先に行いますでしょうか??他に何かいい奇数の判断ってあるでしょうか??ルーズリーフにいろいろ試行錯誤して書いてるのですが、他に何かヒントがあればよろしくお願いします。。。。。 すみませんがお願いします。

  • グレースケール画像を量子化する問題で、量子化レベル数を8階調(N=8)

    グレースケール画像を量子化する問題で、量子化レベル数を8階調(N=8)と設定して画像h=(Ih,Ih,Ih)を生成し、その輝度ヒストグラムを生成せよという問題なのですが。 printf("量子レベル数Nを入力してください"); scanf("%d",&n); dn=256/n; for(j=0;j<nHeight;j++) for(k=0;k<nWidth;k++){ rVal=DllBmpGetPixelValueR(pBmpOrig, j, k); for(i=0;i<n;i++){ if(dn*i<=rVal&&dn*(i+1)>rVal){ f1=dn*i; } DllBmpSetPixelValueR(pBmpCopy1, j, k, f1); DllBmpSetPixelValueG(pBmpCopy1, j, k, f1); DllBmpSetPixelValueB(pBmpCopy1, j, k, f1); ※nHeight:高さ nWidth:幅 rVal=DllBmpGetPixelValueR(pBmpOrig, j, k):赤色成分の輝度値を得る 量子化の公式ΔN=256/N I(x,y)=n*ΔN ifn*ΔN≦I(x,y)<(n+1)*ΔN for∀n={0,N-1} をif文以下で表現しました。 ここまでやってみましたがあとがよくわかりません。 教えてください。 どうかよろしくお願いします。

  • 条件式について・・・・・・・・・・・・

    画像の左下隅と右上隅を結んだ線分を考え、この線分よりも下の三角形の領域をネズミ色(RGB成分の輝度値が128)にした画像を生成するプログラムをやっているのですが、左下隅と右上隅を結んだ線分を考え、この線分よりも下の三角形の領域の色を変えたい場合は、 まず、for(k = 0; k < nWidth; k++) を変えるべきだと思うのですが・・・・・・・四角の画像の右下から上に徐々に色を変えてくかんじだと思うのですが、三角形の公式みたいなのって関係ありますか? /* nWidth:画像の幅、nHeight:画像の高さ、nVal:輝度値*/ int nWidth,nHeight; /* 画像を生成する */ for(j = 0; j < nHeight; j++) for(k = 0; k < nWidth; k++) { DllBmpSetPixelValueR(pBmpOrig, j, k, 255); DllBmpSetPixelValueG(pBmpOrig, j, k, 255); DllBmpSetPixelValueB(pBmpOrig, j, k, 255); } わかる方は、教えてください。よろしくお願いします。

  • 奇数の判断について・・・・・・・・

    y座標が16で割ると余り1になるようなすべてのピクセルを白(RGB成分の輝度値が255)にした画像を生成したい場合・・・・・・・・・ /* nWidth:画像の幅、nHeight:画像の高さ*/ /* x座標とy座標の値を足すと奇数になるすべてのピクセルを白(RGB成分の輝度値が255)にする画像を生成する */  for(j = 0; j < nHeight; j++)   for(k = 0; k < nWidth; k++)   if(k%16==1)     {     DllBmpSetPixelValueR(pBmpOrig, j, k, 255);     DllBmpSetPixelValueG(pBmpOrig, j, k, 255);     DllBmpSetPixelValueB(pBmpOrig, j, k, 255);    } と条件式としましては、if(k%16==1)な感じでも大丈夫でしょうか? すみませんがアドバイスお願いします。。。。。。

  • C言語 プログラミングで行詰まりました…

    標準入力(キーボード)からi,jk,nの値を入力し、次の漸化式を計算し、X_0からX_nまで求めるプログラムを作成したいのですが、うまく表示されません。どかがおかしいのかご指摘お願いします。 <漸化式> X_n=(a+b)/X_(n-1) , X_0=c(n=0) ================================================================== #include<stdio.h> float f_X(int a,int b,float c) { float y; y=(a+b)/c; return y; } int main (void) { int number,i,j; float k,l,n,X; printf("i:"); scanf("%d", &i); printf("j:"); scanf("%d", &j); printf("k:"); scanf("%f", &k); printf("n:"); scanf("%f", &n); X=k; printf("X_0= %.6f\n",X); for(number=1;number<=n;number++) { l=f_X(i,j,X); printf("X_%d= %.6f \n",number,l); X=l; } return 0; } ===================================================================

  • プログラミング

    “初項1公差1の等差数列において、数値XとYを入力して、この数列におけるX項からY項までの数列の和を算出する”プログラムを作っています。 実行結果を 『第X項から:1  第Y項まで:10  初項1公差1の等差数列において、  第1項から第10項までの和は55です。』としたいのですが、 上手くいきません。どこが間違っているのでしょうか? (初心者なのでかなりミスがあると思いますが…。) ↓作ったプログラム #include<stdio.h> main() { int X; int sum = 0; int Y; printf("第X項から:"); scanf("%d",&X); printf("第Y項まで:"); scanf("%d",&Y); while(X <= Y); { sum = sum + X; X = X + 1; } printf("初項1公差1の等差数列において、\n"); printf("第%d",X); printf("項から第%d",Y); printf("項までの数列の和は%d",sum); printf("です。"); }

  • C言語のプログラミングがうまくいきません!

    とりあえず、自分でプログラムしましたが、どこか間違っているようです。僕のプログラムを載せますので、どこが間違っているのか教えて下さい。あと、正しいプログラムを書いていただければ幸いです。 3つの辺の長さをx、y、zに代入して三角形が成立すれば、その形状と面積をヘロンの公式を使って求める。 #include <stdio.h> #include <math.h> { double x ,y, z ,error ,menseki ,ans; printf("x ?") scanf("%f" , &x); printf("y ?") scanf("%f" , &y); printf("z ?") scanf("%f" , &z); ans=(x+y+z)/2; menseki=sqrt(ans*(ans-x)*(ans-y)*(ans-z)); if (x === y || y == z || x == z) { printf ("正三角形です"); printf("面積は%dです" , menseki); } else if (x == y || y == z || z == x) { printf("二等辺三角形です"); printf("面積は%dです" , menseki); } else { printf("三角形です"); printf("面積は%dです , menseki); if(x<y+z || y<x+z || z<x+y) { printf("error"); } }

  • C言語のプログラミングがうまくいきません!

    先日のプログラムを作り直しました。アドバイスのおかげでエラーは減りましたが、まだ完ぺきではないようです。恐らく、elseのところがいけないと思うのですが、どうしたらいいか分かりません。 ご指摘お願いします。 #include <stdio.h> #include <math.h> void main(void) { double x ,y ,z ,error ,menseki ; double ans; printf("x ?"); scanf("%lf", &x); printf("y ?"); scanf("%lf", &y); printf("z ?"); scanf("%lf", &z); if(x<y+z || y<x+z || z<x+y) { ans=(x+y+z)/2; menseki=sqrt(ans*(ans-x)*(ans-y)*(ans-z)); } if(x==y && y==z && z==x) { printf("正三角形です"); printf("面積は%lfです" , menseki); } else if(x==y || y==z || z==x) { printf("二等辺三角形です"); printf("面積は%lfです" , menseki); } else { printf("三角形です"); printf("面積は%lfです" , menseki); } else { printf("error"); } }

専門家に質問してみよう