こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C++での画像切り抜きについて

こんにちは。プログラミング初心者です。

Microsoft Visual Studio C++ MFCで画像解析のプログラムを書いています。
その際、jpg画像から左上隅・右下隅の座標を指定してある領域を切り出したいのですが、
今の方法では切り出した画像の周りに黒の領域ができてしまいます。(添付画像参照)
サイズを切り抜いた画像のサイズに変更して、黒の領域をなくしたいのですが、
どのように書けばいいのでしょうか?
下記のコードに追加する部分・変更する部分を具体的に教えていただけると有難いです。

説明不足で申し訳ありませんが、よろしくお願いいたします。


void CtestbView::OnUleft() //左上隅点の座標
{
// TODO: ここにコマンド ハンドラー コードを追加します。
Lcpx=px; //左上隅のx座標
Lcpy=py; //左上隅のy座標
}


void CtestbView::OnDright() //右下隅点を指定するサブルーチン
{
// TODO: ここにコマンド ハンドラー コードを追加します。
int x,y;
Rcpx=px;//右下隅x座標
Rcpy=py;//y

for(y=Lcpy-1; y<=Rcpy+1; y++) {//切り出し範囲を白線で囲む(白線を切り出さないため+-1を付加)
img1.SetPixel(Lcpx-1,y,RGB(255,255,255)); //左側縦線
img1.SetPixel(Rcpx+1,y,RGB(255,255,255)); //右側縦線
}
for(x=Lcpx-1; x<=Rcpx+1; x++) {
img1.SetPixel(x,Lcpy-1,RGB(255,255,255)); //上側横線
img1.SetPixel(x,Rcpy+1,RGB(255,255,255)); //下側横線
}

jpgLoadFlag1=true;
Invalidate();
}


void CtestbView::OnCut() //テンプレートを切り出すサブルーチン
{
// TODO: ここにコマンド ハンドラー コードを追加します。
int x,y;

BeginWaitCursor();

for(y=0; y<jpgHeight; y++)
for(x=0; x<jpgWidth; x++)
img2.SetPixel(x,y,RGB(0,0,0)); //画面をクリア

int xshift=0;
int yshift=0;
for(y=Lcpy; y<=Rcpy; y++) {
for(x=Lcpx; x<=Rcpx; x++) {
COLORREF color=img1.GetPixel(x,y);
int RV=GetRValue(color);
int GV=GetGValue(color);
int BV=GetBValue(color);
img2.SetPixel(x-Lcpx+xshift,y-Lcpy+yshift,RGB(RV,GV,BV));
}
}

xminP=xshift; xmaxP=Rcpx-Lcpx+xshift; //テンプレート上のパターンの位置
yminP=yshift; ymaxP=Rcpy-Lcpy+yshift;

jpgWidth=xmaxP;
jpgHeight=ymaxP;

jpgLoadFlag2=true;
Invalidate();
EndWaitCursor();
}


void CtestbView::OnLButtonDown(UINT nFlags, CPoint point) //指定点の座標値を取り出す
{
// TODO: ここにメッセージ ハンドラー コードを追加するか、既定の処理を呼び出します。

CView::OnLButtonDown(nFlags, point);
int i,j;
int x,y;

px=point.x; //マウス指定点のx座標
py=point.y; //マウス指定点のy座標

COLORREF color=img1.GetPixel(px,py); //指定点のアドレス変換
rv=GetRValue(color); //マウス指定点の赤成分
gv=GetGValue(color); //マウス指定点の緑座標
bv=GetBValue(color); //マウス指定点の青座標
img1.SetPixel(px, py, RGB(255,0,0));//指定点位置の赤点表示

for(j=0; j<=20; j++)//指定点の色を20×20の短径で表示
for(i=0; i<=20; i++)
img1.SetPixel(jpgWidth-30+i,20+j,RGB(rv,gv,bv)); //指定点の色設定

jpgLoadFlag1=true;
InvalidateRect(NULL);
}

マルチメディアファイルは削除されたか見つかりません。

投稿日時 - 2012-10-24 10:50:40

QNo.7763724

すぐに回答ほしいです

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

新しいサイズで作成し直すのは CImage::Create() で。
ただし、すでに作成済みのイメージを破棄しておく必要があると思いますので、以下のような形で作成します。

// 既存のイメージがあれば破棄
if (!img2.IsNull()) { img2.Destroy(); }

// 新しいサイズで24bitビットマップ作成
img2.Create(Rcpx-Lcpx, Rcpy-Lcpy, 24);


また、もしビットマップをピクチャボックスコントロール(CStatic)に割り当てているのであれば、コントロールの SetBitmap() を呼び出して再度関連付ける必要があります。ピクチャコントロールの変数が pic であるなら以下のように。

pic.SetBitmap(img2);

投稿日時 - 2012-10-29 20:44:06

お礼

丁寧なご回答ありがとうございます。

fresh_homepieさんの方法でやりたかった処理ができるようになりました。

また色々と質問させていただくと思いますが、お時間ございましたらご回答よろしくお願いいたします。

投稿日時 - 2012-10-30 11:35:49

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

添付画像が見えない状態ですし、メンバ定義等も不明で確かなことは言えませんが…

コピーしようとしているサイズ (Rcpx-Lcpx, Rcpy-Lcpy) がコピー先領域のサイズ (jpgHeight, jpgWidth) より小さいために、差分領域が黒くなっているのでしょう。
表示を小さくするのであればコピー先CImage(かな?)をコピーするサイズに合った大きさで作り直す必要があります。

その他には、そもそもコピー元のオリジナルイメージであるはずの img1 自体に線を引いたり点を描いたりしているのもまずいのでは? と思いますが…。

投稿日時 - 2012-10-27 22:44:53

補足

ご回答ありがとうございます。

著作権に関するご指摘があったため、添付画像は削除させていただきました。
原因についてはfresh_homepieさんのご指摘通りだと思います。
コピー先CImageをコピーするサイズに合った大きさで作り直すとは具体的にどのようにすればいいのでしょうか。

よろしくお願いいたします。

投稿日時 - 2012-10-29 15:19:54

お礼

ありがとうございました(^^)

投稿日時 - 2012-11-03 23:35:54

あなたにオススメの質問