Direct2d , WICBITMAP
private:
ID2D1Factory* m_pDirect2dFactory;
ID2D1HwndRenderTarget* m_pRenderTarget;
ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
ID2D1SolidColorBrush* m_pCornflowerBlueBrush;
ID2D1Bitmap* m_pD2d1Bitmap;
IWICBitmap* m_pWicBitmap;
IWICImagingFactory* m_pWicImagingFactory;
IWICBitmapDecoder* m_pWicDecoder;
IWICBitmapFrameDecode* m_pWicFrameDecoder;
// Initialize device-indpendent resources, such
// as the Direct2D factory.
HRESULT DemoApp::CreateDeviceIndependentResources()
{
HRESULT hr = S_OK;
// Create a Direct2D factory.
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pDirect2dFactory);
hr = CoCreateInstance(CLSID_WICImagingFactory,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&m_pWicImagingFactory));
return hr;
}
if(m_pWicImagingFactory != nullptr)
{
m_pWicImagingFactory->CreateDecoderFromFilename(L"1.jpg",nullptr,GENERIC_READ,WICDecodeMetadataCacheOnDemand,&m_pWicDecoder);
m_pWicDecoder->GetFrame(0,&m_pWicFrameDecoder);
IWICBitmapSource* pWicSource = nullptr;
m_pWicFrameDecoder->QueryInterface(IID_PPV_ARGS(&pWicSource));
IWICFormatConverter* pCovert = nullptr;
// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
m_pWicImagingFactory->CreateFormatConverter(&pCovert);
hr = pCovert->Initialize(
pWicSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeCustom
);
m_pWicImagingFactory->CreateBitmapFromSource(pCovert,WICBitmapCacheOnDemand,&m_pWicBitmap);
SafeRelease(&pCovert);
UINT pixelWidth = 0,pixelHeight = 0;
m_pWicBitmap->GetSize(&pixelWidth,&pixelHeight);
}
HRESULT DemoApp::CreateDeviceResources()
{
HRESULT hr = S_OK;
if (!m_pRenderTarget)
{
RECT rc;
GetClientRect(m_hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// Create a Direct2D render target.
hr = m_pDirect2dFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(m_hwnd, size),
&m_pRenderTarget
);
if (SUCCEEDED(hr))
{
// Create a gray brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::LightSlateGray),
&m_pLightSlateGrayBrush
);
}
if (SUCCEEDED(hr))
{
// Create a blue brush.
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
&m_pCornflowerBlueBrush
);
}
if (SUCCEEDED(hr))
{
m_pRenderTarget->CreateBitmapFromWicBitmap(m_pWicBitmap,NULL,&m_pD2d1Bitmap);
}
}
return hr;
}
HRESULT DemoApp::OnRender()
{
HRESULT hr = S_OK;
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::AntiqueWhite));
D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
// Draw a grid background.
int width = static_cast<int>(rtSize.width);
int height = static_cast<int>(rtSize.height);
for (int x = 0; x < width; x += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(static_cast<FLOAT>(x), 0.0f),
D2D1::Point2F(static_cast<FLOAT>(x), rtSize.height),
m_pLightSlateGrayBrush,
0.5f
);
}
for (int y = 0; y < height; y += 10)
{
m_pRenderTarget->DrawLine(
D2D1::Point2F(0.0f, static_cast<FLOAT>(y)),
D2D1::Point2F(rtSize.width, static_cast<FLOAT>(y)),
m_pLightSlateGrayBrush,
0.5f
);
}
// Draw two rectangles.
D2D1_RECT_F rectangle1 = D2D1::RectF(
rtSize.width/2 - 50.0f,
rtSize.height/2 - 50.0f,
rtSize.width/2 + 50.0f,
rtSize.height/2 + 50.0f
);
D2D1_RECT_F rectangle2 = D2D1::RectF(
rtSize.width/2 - 100.0f,
rtSize.height/2 - 100.0f,
rtSize.width/2 + 100.0f,
rtSize.height/2 + 100.0f
);
// Draw a filled rectangle.
m_pRenderTarget->FillRectangle(&rectangle1, m_pLightSlateGrayBrush);
// Draw the outline of a rectangle.
m_pRenderTarget->DrawRectangle(&rectangle1, m_pCornflowerBlueBrush);
if(m_pD2d1Bitmap != nullptr)
{
D2D1_SIZE_U sizeU = m_pD2d1Bitmap->GetPixelSize();
D2D1_RECT_F rectangle3 = D2D1::RectF(
(rtSize.width - sizeU.width)*0.5f,
(rtSize.height - sizeU.height)*0.5f,
sizeU.width + (rtSize.width - sizeU.width)*0.5f ,
sizeU.height + (rtSize.height - sizeU.height)*0.5f
);
m_pRenderTarget->DrawBitmap(m_pD2d1Bitmap,&rectangle3,1.0f);
}
hr = m_pRenderTarget->EndDraw();
}
if (hr == D2DERR_RECREATE_TARGET)
{
hr = S_OK;
DiscardDeviceResources();
}
return hr;
}
void DemoApp::DiscardDeviceResources()
{
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
示例:
#pragma once
using namespace Platform;
using namespace Windows::UI::Xaml::Media::Imaging;
namespace ApplicationHelpers
{
public ref class ImageComponent sealed
{
public:
ImageComponent();
public:
Array<byte>^ GetBitmap(String^ filePath);
private:
HRESULT CreateDeviceIndependentResources();
//HRESULT CreateDeviceResources();
byte* BufferFromWriteableBitmap(WriteableBitmap^ bitmap);
private:
ID2D1Factory1* m_pD2dFactory;
ID2D1RenderTarget* m_pRenderTarget;
ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
ID2D1SolidColorBrush* m_pCornflowerBlueBrush;
ID2D1Bitmap* m_pD2d1Bitmap;
IWICImagingFactory* m_pWicFactory;
IWICBitmap* m_pWicBitmap;
IWICBitmapDecoder* m_pWicDecoder;
IWICBitmapFrameDecode* m_pWicFrameDecoder;
};
}
#include "pch.h"
#include "ImageComponent.h"
#include "Robuffer.h"
using namespace ApplicationHelpers;
using namespace Windows::Storage::Streams;
ImageComponent::ImageComponent()
{
CreateDeviceIndependentResources();
}
HRESULT ImageComponent::CreateDeviceIndependentResources()
{
HRESULT hr = S_OK;
// Create a Direct2D factory.
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1),
nullptr,
(void**)&m_pD2dFactory
);
hr = CoCreateInstance(CLSID_WICImagingFactory,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&m_pWicFactory));
return hr;
}
Array<byte>^ ImageComponent::GetBitmap(String^ filePath)
{
HRESULT hr=S_OK;
IWICBitmapSource* pWicSource = nullptr;
IWICFormatConverter* pCovert = nullptr;
if(m_pWicFactory != nullptr)
{
m_pWicFactory->CreateDecoderFromFilename(
filePath->Data(),
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnDemand,
&m_pWicDecoder
);
m_pWicDecoder->GetFrame(0,&m_pWicFrameDecoder);
m_pWicFrameDecoder->QueryInterface(IID_PPV_ARGS(&pWicSource));
// Convert the image format to 32bppPBGRA
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
m_pWicFactory->CreateFormatConverter(&pCovert);
hr = pCovert->Initialize(
pWicSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeCustom
);
m_pWicFactory->CreateBitmapFromSource(pCovert,WICBitmapCacheOnDemand,&m_pWicBitmap);
UINT pixelWidth = 0,pixelHeight = 0;
m_pWicBitmap->GetSize(&pixelWidth,&pixelHeight);
hr = m_pWicFactory->CreateBitmap(
pixelWidth,
pixelHeight,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapCacheOnDemand,
&m_pWicBitmap
);
//create render target
hr = m_pD2dFactory->CreateWicBitmapRenderTarget(
m_pWicBitmap,
D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_SOFTWARE),
&m_pRenderTarget
);
hr = m_pRenderTarget->CreateBitmapFromWicBitmap(
pCovert,
D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,D2D1_ALPHA_MODE_PREMULTIPLIED)),
&m_pD2d1Bitmap
);
m_pRenderTarget->BeginDraw();
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Black,0.f));
m_pRenderTarget->DrawBitmap(m_pD2d1Bitmap,D2D1::RectF(0,0,(float)pixelWidth,(float)pixelHeight));
m_pRenderTarget->EndDraw();
WICRect rcLock = { 0, 0, pixelWidth, pixelHeight };
IWICBitmapLock* pLock = nullptr;
m_pWicBitmap->Lock(&rcLock,WICBitmapLockRead,&pLock);
UINT pcbBufferSize = 0;
byte* ppbData = nullptr;
pLock->GetDataPointer(&pcbBufferSize,&ppbData);
/*auto bitmap=ref new WriteableBitmap(pixelWidth, pixelHeight);
byte* bytes = BufferFromWriteableBitmap(bitmap);
memcpy(bytes, ppbData, pcbBufferSize);
bitmap->Invalidate();
return bitmap;*/
auto bytes=ref new Array<byte>(pcbBufferSize);
memcpy(bytes->Data,ppbData, pcbBufferSize);
SafeRelease(&pWicSource);
SafeRelease(&pCovert);
SafeRelease(&pLock);
return bytes;
}
return nullptr;
}
byte* ImageComponent::BufferFromWriteableBitmap(WriteableBitmap^ bitmap)
{
IUnknown* pUnknown = reinterpret_cast<IUnknown*>(bitmap->PixelBuffer);
IBufferByteAccess* pBufferByteAccess = nullptr;
HRESULT hr = pUnknown->QueryInterface(IID_PPV_ARGS(&pBufferByteAccess));
pUnknown->Release();
byte *pPixels = nullptr;
hr = pBufferByteAccess->Buffer(&pPixels);
return pPixels;
}
/* *
//var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(@"ms-appx:///Assets/1.jpg"));
var file = await Package.Current.InstalledLocation.GetFileAsync(@"Assets\1.jpg");
if (file != null)
{
var properties = await file.Properties.GetImagePropertiesAsync();
var bitmap = new WriteableBitmap((int)properties.Width, (int)properties.Height);
using (var randomAccessStream = await file.OpenReadAsync())
{
bitmap.SetSource(randomAccessStream);
image.Source = bitmap;
image.Width = bitmap.PixelWidth;
image.Height = bitmap.PixelHeight;
bitmap.Invalidate();
}
}
* */
var bytes = _imageComponent.GetBitmap(@"Assets/1.jpg");
if (bytes != null)
{
var bitmap = CommonHelper.ConvertByteToWriteableBitmap(bytes, 1366, 768);
image.Source = bitmap;
image.Width = bitmap.PixelWidth;
image.Height = bitmap.PixelHeight;
bitmap.Invalidate();
}
环境:Windows8 Pro +Visual Studio 2012 Ultimate