こんばんは。補足頂きました。
すんません、思いっきり的外れな事を書いてしまいました。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でやってみます。 ありがとうございました。