我正在做的是使用turbojpeg读取greyscale jpeg,使用其数据创建Gdiplus :: Bitmap并尝试使用Gdiplus :: Graphics绘制它。一切都很好,直到我尝试绘制图像 - 我得到Unhandled exception at 0x74123193 in program.exe: 0xC0000005: Access violation reading location 0x04ac7848.
显然正确地创建了位图 - Bitmap::lastResult == Ok
。我的代码如下所示:
// Initialize GDI+.
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// creating program window
Graphics = new Gdiplus::Graphics(GetDC(hwnd));
Graphics->SetCompositingMode( Gdiplus::CompositingModeSourceCopy );
Graphics->SetCompositingQuality( Gdiplus::CompositingQualityHighSpeed );
Graphics->SetPixelOffsetMode( Gdiplus::PixelOffsetModeNone );
Graphics->SetSmoothingMode( Gdiplus::SmoothingModeNone );
Graphics->SetInterpolationMode( Gdiplus::InterpolationModeDefault );
// loading jpeg using turbojpeg
std::vector<unsigned char> data;
int width,
height;
std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
long begin,end;
begin = (long)ifs.tellg();
ifs.seekg (0, std::ios::end);
end = (long)ifs.tellg();
long size = end - begin;
ifs.seekg(0);
std::vector<char> jpegdata(size);
unsigned char* dataptr = reinterpret_cast<unsigned char*>(&jpegdata[0]);
ifs.read(&jpegdata[0], jpegdata.size());
tjhandle handle = tjInitDecompress();
tjDecompressHeader(handle, dataptr, jpegdata.size(), &width, &height);
data.resize(width * height);
tjDecompress2(handle, dataptr, jpegdata.size(), &data[0], width, width, height, TJPF_GRAY, 0);
tjDestroy(handle);
// creating Gdiplus::Bitmap
Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap(width,
height,
width * 8,
PixelFormat8bppIndexed,
(BYTE*)&data[0]);
// drawing bitmap
Graphics->DrawImage(bitmap, 0, 0);
抛出异常
Graphics->DrawImage(bitmap, 0, 0);
这种行为的原因是什么?我做错了什么?
edit
设置正确的步幅为user1837009建议修复了异常。
有一个原因我使用这个特殊的构造函数 - 我需要尽可能使原始图像数据,灰度,每像素8位进行一些转换。而且我很确定在调用data
之后我在tjDecompress2
变量中的含义。不幸的是,似乎没有支持8位灰度像素格式,只有PixelFormat16bppGrayScale,这是16位。关于如何解决这个问题的任何想法?
答案 0 :(得分:2)
这里有几个问题:
PixelFormat8bppIndexed
。 修复上述两点和三点非常简单(使用右侧步幅和右侧像素格式)。要修复点1意味着您必须以理智的方式读取JPEG图像。
然而,当然有一个更简单的解决方案:使用Bitmap.Bitmap(const WCHAR*, BOOL)
,它将直接加载JPEG图像,而不必处理与“如何解码JPEG图像有关的任何事情。”
答案 1 :(得分:0)
读取:https://msdn.microsoft.com/en-us/library/windows/desktop/ms536315(v=vs.85).aspx
for stride param。
所以试试,
Gdiplus :: Bitmap bitmap = new Gdiplus :: Bitmap(width, 高度, 宽度, PixelFormat8bppIndexed, (BYTE )及数据[0]);