WICConvertBitmapSource + CopyPixel结果为蓝色图像
WICConvertBitmapSource + CopyPixels results in blue image
我正在尝试使用 WIC 将图像加载到内存缓冲区中进行进一步处理,然后在完成后将其写回文件。 具体说来:
- 将图像加载到 IWICBitmapFrameDecode 中。
- 加载的IWICBitmapFrameDecode报告其像素格式为GUID_WICPixelFormat24bppBGR。我想在32bpp RGBA中工作,所以我打电话给WICConvertBitmapSource。
- 在转换后的帧上调用 CopyPixel 以获取内存缓冲区。
- 使用 WritePixel 将内存缓冲区写回 IWICBitmapFrameEncode。
这会产生可识别的图像,但生成的图像大多是蓝色的,就好像红色通道被解释为蓝色一样。
如果我调用 WriteSource 直接写入转换后的帧,而不是写入内存缓冲区,它可以工作。 如果我从原始未转换的帧调用 CopyPixel(并相应地更新我的步幅和像素格式(,它可以工作。 只有WICConvertBitmapSource的组合加上内存缓冲区(CopyPixel + WritePixels(的使用导致了问题,但我无法弄清楚我做错了什么。
这是我的代码。
int main() {
IWICImagingFactory *pFactory;
IWICBitmapDecoder *pDecoder = NULL;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
(LPVOID*)&pFactory
);
// Load the image.
pFactory->CreateDecoderFromFilename(L"input.png", NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &pDecoder);
IWICBitmapFrameDecode *pFrame = NULL;
pDecoder->GetFrame(0, &pFrame);
// pFrame->GetPixelFormat shows that the image is 24bpp BGR.
// Convert to 32bpp RGBA for easier processing.
IWICBitmapSource *pConvertedFrame = NULL;
WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, pFrame, &pConvertedFrame);
// Copy the 32bpp RGBA image to a buffer for further processing.
UINT width, height;
pConvertedFrame->GetSize(&width, &height);
const unsigned bytesPerPixel = 4;
const unsigned stride = width * bytesPerPixel;
const unsigned bitmapSize = width * height * bytesPerPixel;
BYTE *buffer = new BYTE[bitmapSize];
pConvertedFrame->CopyPixels(nullptr, stride, bitmapSize, buffer);
// Insert image buffer processing here. (Not currently implemented.)
// Create an encoder to turn the buffer back into an image file.
IWICBitmapEncoder *pEncoder = NULL;
pFactory->CreateEncoder(GUID_ContainerFormatPng, nullptr, &pEncoder);
IStream *pStream = NULL;
SHCreateStreamOnFileEx(L"output.png", STGM_WRITE | STGM_CREATE, FILE_ATTRIBUTE_NORMAL, true, NULL, &pStream);
pEncoder->Initialize(pStream, WICBitmapEncoderNoCache);
IWICBitmapFrameEncode *pFrameEncode = NULL;
pEncoder->CreateNewFrame(&pFrameEncode, NULL);
pFrameEncode->Initialize(NULL);
WICPixelFormatGUID pixelFormat = GUID_WICPixelFormat32bppRGBA;
pFrameEncode->SetPixelFormat(&pixelFormat);
pFrameEncode->SetSize(width, height);
pFrameEncode->WritePixels(height, stride, bitmapSize, buffer);
pFrameEncode->Commit();
pEncoder->Commit();
pStream->Commit(STGC_DEFAULT);
return 0;
}
PNG 编码器仅支持 PNG 本机编解码器官方文档中指定的 32bppGUID_WICPixelFormat32bppBGRA
(BGR(。当你用GUID_WICPixelFormat32bppRGBA
调用它时,它不会进行信道切换。只会使用你的像素,因为它们是 BGR,而不是 RGB,并且不会告诉你有问题。
我不知道你想做什么,但是在你的例子中,你可以在对WICConvertBitmapSource的调用中用GUID_WICPixelFormat32bppBGRA
替换GUID_WICPixelFormat32bppRGBA
(也可以替换最后一个pixelFormat
变量的定义以确保你的源代码是正确的,但它不会改变任何东西(。
PS:您可以使用Wic保存文件,而无需使用其他API创建流,请在此处查看我的答案: 使用DirectX捕获屏幕
相关文章:
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 将图像添加到资源文件夹UWP C++
- 彩色图像的卤化物处理平均值
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 重新定位图像时如何前进到下一个内存块
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 为什么 BMP 图像上的 imwrite 会卡住/不返回?
- Gstreamer:每 5 秒使用多文件墨水保存图像/jpeg
- 如何使用CImg打开图像?
- WICConvertBitmapSource + CopyPixel结果为蓝色图像
- 如果新图像中的原始像素为黑色,则Qt绘制一个蓝色像素