![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
今、画像を拡大して表示する処理を作成しています。
実際の処理としては以下のような感じです。
Graphics^ g = Graphics::FromImage(picView->Image);
g->InterpolationMode = Drawing2D::InterpolationMode::NearestNeighbor;
g->DrawImage(imgTemp, 0, 0, nWidth * nScale, nHeight * nScale);
画像を拡大して表示すること自体はできているのですが、
拡大の基準点?がずれているような表示になるのが気になります。
たとえば、拡大前の画像が市松模様だったとして、拡大後は
□□■■□□■■□□■■
□□■■□□■■□□■■
■■□□■■□□■■□□
■■□□■■□□■■□□
□□■■□□■■□□■■
□□■■□□■■□□■■
■■□□■■□□■■□□
■■□□■■□□■■□□(図1)
のように表示して欲しいのですが、実際の表示は
□■■□□■■□□■■
■□□■■□□■■□□
■□□■■□□■■□□
□■■□□■■□□■■
□■■□□■■□□■■
■□□■■□□■■□□
■□□■■□□■■□□(図2)
のような感じで、左端と上端が半分くらいしか見えてない感じです。
(8倍に拡大したとして、4ピクセルの白、8ピクセルの黒…となっている感じです)
(図1)のように表示されるにはどのようにすればいいでしょうか?
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
こんばんは。
補足頂きました。すんません、思いっきり的外れな事を書いてしまいました。Visual Studio 2008 C++/CLIで以下のコードで試して見ました。
見事に1ピクセル分ずれました。Graphics::DrawImage()メソッドのバグである可能性が濃厚です。
まともに等価倍率コピーが出来ないのですから、ルーペ表示的な機能を実装する上では、使い物にならないと思います。
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
this->pictureBox1->Image = gcnew Bitmap("test.bmp");
this->pictureBox1->Image->Save("kakunin.bmp");
const int nWidth = this->pictureBox1->Image->Width;
const int nHeight= this->pictureBox1->Image->Height;
const int nScale = 2;
Bitmap^ imgTemp = gcnew Bitmap(nWidth * nScale, nHeight * nScale, this->pictureBox1->Image->PixelFormat);
Graphics^ g = Graphics::FromImage(imgTemp);
g->InterpolationMode = Drawing2D::InterpolationMode::NearestNeighbor;
g->DrawImage(this->pictureBox1->Image, 0, 0, nWidth * nScale, nHeight * nScale);
imgTemp->Save("stretch.bmp");//此処で出力されたビットマップファイルもズレている
this->pictureBox1->Image = imgTemp;
this->pictureBox1->Invalidate();
}
win32 apiの出番かもしれません。以下でまともに出力されました。以下参考程度に。
#include<windows.h>
#pragma comment(lib, "gdi32.lib")
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
this->pictureBox1->Image = gcnew Bitmap("test.bmp");
this->pictureBox1->Image->Save("kakunin.bmp");
const int nWidth = this->pictureBox1->Image->Width;
const int nHeight= this->pictureBox1->Image->Height;
const int nScale = 2;
Bitmap^ imgTemp = gcnew Bitmap(nWidth * nScale, nHeight * nScale, this->pictureBox1->Image->PixelFormat);
IntPtr iPtrDst = imgTemp->GetHbitmap();
IntPtr iPtrSrc = static_cast<Bitmap^>(this->pictureBox1->Image)->GetHbitmap();
HDC hDCDst = ::CreateCompatibleDC(NULL);
HDC hDCSrc = ::CreateCompatibleDC(NULL);
HBITMAP hBmpDst = static_cast<HBITMAP>(iPtrDst.ToPointer());
HBITMAP hBmpSrc = static_cast<HBITMAP>(iPtrSrc.ToPointer());
HGDIOBJ hBmpDstOld = ::SelectObject(hDCDst, hBmpDst);
HGDIOBJ hBmpSrcOld = ::SelectObject(hDCSrc, hBmpSrc);
::StretchBlt(hDCDst, 0, 0, nWidth * nScale, nHeight * nScale, hDCSrc, 0, 0, nWidth, nHeight, SRCCOPY);
::SelectObject(hDCDst, hBmpDstOld);
::SelectObject(hDCSrc, hBmpSrcOld);
::DeleteDC(hDCDst);
::DeleteDC(hDCSrc);
imgTemp = Bitmap::FromHbitmap(iPtrDst);
imgTemp->Save("stretch.bmp");
::DeleteObject(hBmpDst);
::DeleteObject(hBmpSrc);
this->pictureBox1->Image = imgTemp;
this->pictureBox1->Invalidate();
}
どうもDrawImageを使う限り、この「ずれ」からは逃れられないみたいですね。
調べてみたところ、バグというよりは補間をした結果の「ずれ」みたいな感じです。
考え方の違いというか。
拡大前の座標が 0.5000~1.4999 になる範囲に 1.0000 の座標の色が拡大されている感じで。
言葉では説明しにくいんですが、
元々の画素を拡大後の座標に配置
↓
開いた隙間を、配置した画素の色(の範囲)を広げて埋める
みたいな感じですかね?
それぞれの画素から滲み出した色が(混ざらないで)広がった結果、こうなった的な。
Win32APIを使う方法は今までもやったことはあるんですが、あまりC++的じゃないというか、純粋なCっぽいので避けてました。
今回はWin32APIのお世話になるのが正解なんでしょうかね。
ひとまずDrawImageはやめてWin32APIでやってみます。
ありがとうございました。
No.1
- 回答日時:
こんにちは。
恐らく、
g->InterpolationMode = Drawing2D::InterpolationMode::NearestNeighbor;
辺りが原因かもしれません。
http://msdn.microsoft.com/ja-jp/library/system.d …
上記の、
g->InterpolationMode = Drawing2D::InterpolationMode::Default;
又は、
g->InterpolationMode = Drawing2D::InterpolationMode::Invalid;
辺りで試されて見ては如何でしょうか。
この回答への補足
~::Defaultなどでは拡大したときに補完をしてしまいます。
今回やりたいのは、ルーペツールなどのように「そのまま」拡大する処理なんです。
こういった処理はDrawImageではできないんでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Windows 8 Route Generator の使い方 1 2023/05/03 00:36
- その他(ソフトウェア) 画像の拡大率を固定したまま次の画像を表示出来るビューアを探しています 2 2022/05/13 17:19
- デジタルカメラ 録画した4K動画を、フルピクセルで再生したい 5 2023/05/10 00:05
- その他(IT・Webサービス) Yahooの地図の文字サイズ、googleの地図の画面分割 1 2022/05/21 12:31
- X(旧Twitter) ツィッターの画像表示について 1 2023/08/17 09:28
- その他(ソフトウェア) IrfanView で画像のスクロール?できますか 1 2022/08/31 13:57
- 一眼レフカメラ 誰の意見が信用できるか 6 2022/11/07 19:32
- その他(パソコン・スマホ・電化製品) CMD等でPC操作(excel開く等)を自動化させたい 1 2023/03/15 09:53
- 一眼レフカメラ カメラ選び 6 2022/09/02 12:54
- Windows 7 Windows画面表示について 3 2023/04/23 11:50
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CListCtrlのcheckboxサイズ変更
-
素材屋さんでよく見かける、壁...
-
jquery(js)にて実装したいスラ...
-
電話番号のフォーマットについて
-
Dosブロンプトでtabを出力したい
-
wordの差し込み印刷で文字...
-
「取得先」という表現について
-
開始と終了を指定して、その間...
-
VBA コレクションに2次元配列...
-
URLのパラメータをGETのままで...
-
【C#】DataGridViewの最大列数...
-
<A href ~で複数の値を渡したい
-
バッチファイルでpingの結果を...
-
shシェルスクリプト 空白行の...
-
DTOとEntityの差は何ですか。
-
excel access連携 このテーブル...
-
「ログイン機能を持たせる」説...
-
VB.NETからVBAマクロ(引数)を呼...
-
Windowsのsetコマンドでの小数...
-
XMLHttpRequestでウェブページ取得
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DrawImageでビットマップを拡大...
-
PHP リロードせずに、リアルタ...
-
VB.NETで画像の拡大・縮小
-
OpenFileDialogの自作
-
一時停止と再開
-
HTML上の画像にマウスオーバー...
-
gooのフィードを作成したのです...
-
C#【フォルダの参照】ダイアログ
-
過去の書込みで・・・どのよう...
-
Dosブロンプトでtabを出力したい
-
DTOとEntityの差は何ですか。
-
「取得先」という表現について
-
switch()文で値の大小比較
-
wordの差し込み印刷で文字...
-
バッチファイルでpingの結果を...
-
shシェルスクリプト 空白行の...
-
Yahoo! JAPAN IDを新規取得でき...
-
【C#】DataGridViewの最大列数...
-
phpでcookieがうまく保存されない
-
URLのパラメータをGETのままで...
おすすめ情報