问题描述
我正在制作一个用于图像编辑的 .NET 应用程序。为了在 PictureBox 中显示图像,我使用 IWIC 打开它以转换为 HBITMAP,然后使用 FromHbitmap 方法将其粘贴到 PictureBox 中。这意味着虽然应用程序中存在 Image 实例,但我无法使用它。那么如何更改我的阅读器类以访问图像?
IMGReader.h
tf.keras.callbacks.EarlyStopping(
monitor='val_loss',<------------
min_delta=0,patience=0,verbose=0,mode='auto',baseline=None,restore_best_weights=False
)
IMGReader.cpp
#pragma once
#include <wincodec.h> // WIC codec header for decoding image from file
#include "StringConverter.h"
#pragma comment (lib,"windowscodecs")
class IMGReader
{
IWICFormatConverter* wConverter;
UINT BitHeight;
UINT BitWidth;
IMGReader() {};
BOOLEAN pathExist(LPCWSTR path);
public:
IMGReader(LPCWSTR path) { load(path); };
~IMGReader() { wConverter->Release(); };
void load(LPCWSTR path);
UINT getBitmapHeight() { return BitHeight; };
UINT getBitmapWidth() { return BitWidth; };
HBITMAP IWICBitmapToHBITMAP();
};
以主要形式使用:
#include "IMGReader.h"
#include "MTTErrorLogger.h"
#include <filesystem>
#include <vector>
void IMGReader::load(LPCWSTR path)
{
HRESULT hr; // For checking errors
if (!pathExist(path)) { path = L"nodata.jpg"; }; // Check if image really exist in this derectory
// Craete WIC factory
IWICImagingFactory* wicFactory = NULL;
hr = CoCreateInstance(
CLSID_WICImagingFactory,// CLS ID of the object making
NULL,// Not part of agregate
CLSCTX_INPROC_SERVER,// DLL runs in the same process
IID_IWICImagingFactory,// Ref to interface that communicates with the object
(LPVOID*)&wicFactory // The pointer that'll contain factory
);
// Create decoder
IWICBitmapDecoder* wicDecoder = NULL;
hr = wicFactory->CreateDecoderFromFilename(
path,// Path to reading file
NULL,// No preferred vendor
GENERIC_READ,// Reading file
WICDecodeMetadataCacheOnLoad,// Cache on load
&wicDecoder // Making decoder
);
// Read frame from the image
IWICBitmapFrameDecode* wicFrame = NULL;
hr = wicDecoder->GetFrame(0,&wicFrame);
//Create converter
IWICFormatConverter* wicConverter = NULL;
hr = wicFactory->CreateFormatConverter(&wicConverter);
// Setup the converter
hr = wicConverter->Initialize(
wicFrame,// Frame
GUID_WICPixelFormat32bppPBGRA,// Pixel format
WICBitmapDitherTypeNone,// Irrelevant
NULL,// No palette needed,irrelevant
0.0,// Alpha transparency % irrelevant
WICBitmapPaletteTypeCustom // Irrelevant
);
wicConverter->GetSize(&BitHeight,&BitWidth);
wConverter = wicConverter;
}
HBITMAP IMGReader::IWICBitmapToHBITMAP()
{
UINT height = BitHeight; // Bitmap height
UINT width = BitWidth; // Bitmap width
wConverter->GetSize(&width,&height);
std::vector<BYTE> buffer(width * height * 4);
wConverter->copyPixels(0,width * 4,buffer.size(),buffer.data());
HBITMAP bitmap = CreateBitmap(width,height,1,32,buffer.data()); // Create bitmap from IWICBitmap data
return bitmap;
}
BOOLEAN IMGReader::pathExist(LPCWSTR path)
{
if (std::filesystem::exists(path)) {
return true;
}
return false;
}
谢谢。
解决方法
所以我解决了这个问题。问题似乎是我没有将图像数据存储在特定位置,而是每次在加载方法中创建新的。我在代码中做了以下修改:
标题:
#pragma once
#include <wincodec.h> // WIC codec header for decoding image from file
#include <atlcomcli.h>
#include "StringConverter.h"
#pragma comment (lib,"windowscodecs")
class IMGReader
{
CComPtr<IWICImagingFactory> m_pImagingFactory;
CComPtr<IWICBitmapDecoder> m_pBitmapDecoder;
CComPtr<IWICBitmapFrameDecode> m_pFrameDecoder;
CComPtr<IWICFormatConverter> m_pConverter;
UINT BitHeight;
UINT BitWidth;
BOOLEAN pathExist(LPCWSTR path);
IMGReader() {};
public:
IMGReader(LPCWSTR path) { load(path); };
~IMGReader() { SafeRelease(&m_pConverter); };
void load(LPCWSTR path);
void clean();
template <class T> void SafeRelease(T** ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
UINT getBitmapHeight() { return BitHeight; };
UINT getBitmapWidth() { return BitWidth; };
HBITMAP IWICBitmapToHBITMAP();
};
实施:
void IMGReader::load(LPCWSTR path)
{
HRESULT hr;
m_pImagingFactory = NULL;
m_pBitmapDecoder = NULL;
m_pFrameDecoder = NULL;
m_pConverter = NULL;
hr = CoCreateInstance(
CLSID_WICImagingFactory,// CLS ID of the object making
NULL,// Not part of agregate
CLSCTX_INPROC_SERVER,// DLL runs in the same process
IID_IWICImagingFactory,// Ref to interface that communicates with the object
(LPVOID*)&m_pImagingFactory // The pointer that'll contain factory
);
hr = m_pImagingFactory->CreateDecoderFromFilename(
path,// Path to reading file
NULL,// No preferred vendor
GENERIC_READ,// Reading file
WICDecodeMetadataCacheOnLoad,// Cache on load
&m_pBitmapDecoder // Making decoder
);
hr = m_pBitmapDecoder->GetFrame(0,&m_pFrameDecoder);
hr = m_pImagingFactory->CreateFormatConverter(&m_pConverter);
hr = m_pConverter->Initialize(
m_pFrameDecoder,// Frame
GUID_WICPixelFormat32bppPBGRA,// Pixel format
WICBitmapDitherTypeNone,// Irrelevant
NULL,// No palette needed,irrelevant
0.0,// Alpha transparency % irrelevant
WICBitmapPaletteTypeCustom // Irrelevant
);
this->m_pConverter->GetSize(&BitHeight,&BitWidth);
}