C# - 转换WPF Image.source到System.Drawing.Bitmap [英] C# - Convert WPF Image.source to a System.Drawing.Bitmap
问题描述
我发现人们转换BitmapSources位图负荷,但对于ImageSources位图?我想提出的成像程序,我需要从图像元素显示的图像中提取的位图。有谁知道如何做到这一点?
编辑1:
这是对位图图像转换为位图的功能。记得设置编译器preferences的不安全的选项。
公共静态System.Drawing.Bitmap BitmapSourceToBitmap(SRS的BitmapSource)
{
System.Drawing.Bitmap BTM = NULL; INT宽度= srs.PixelWidth; INT高度= srs.PixelHeight; INT跨距=宽*((srs.Format.BitsPerPixel + 7)/ 8); 字节[]位=新的字节[高*步幅]。 srs.CopyPixels(比特,步幅,0); 不安全
{ 固定(字节* PB =位)
{
IntPtr的PTR =新的IntPtr(PB); BTM =新System.Drawing.Bitmap(宽度,高度,跨度,System.Drawing.Imaging.PixelFormat.Format1bppIndexed,PTR);
}
}
返回BTM;
}
下一页现在是获得一个位图图像:
RenderTargetBitmap targetBitmap =新RenderTargetBitmap(
(INT)inkCanvas1.ActualWidth,
(INT)inkCanvas1.ActualHeight,
96D,96D,
PixelFormats.Default); targetBitmap.Render(inkCanvas1); MemoryStream的MSE =新的MemoryStream();
System.Windows.Media.Imaging.BmpBitmapEn codeR纪念品=新BmpBitmapEn codeR();
mem.Frames.Add(BitmapFrame.Create(targetBitmap));
mem.Save(MSE); mse.Position = 0;
BitmapImage的双向=新的BitmapImage();
bi.BeginInit();
bi.StreamSource = MSE;
bi.EndInit();
下一步是将其转换:
位图B =新位图(BitmapSourceToBitmap(BI));
其实你并不需要使用不安全code。有 CopyPixels
的接受一个IntPtr过载:
公共静态System.Drawing.Bitmap BitmapSourceToBitmap2(SRS的BitmapSource)
{
INT宽度= srs.PixelWidth;
INT高度= srs.PixelHeight;
INT跨距=宽*((srs.Format.BitsPerPixel + 7)/ 8);
IntPtr的PTR = IntPtr.Zero;
尝试
{
PTR = Marshal.AllocHGlobal(高*步幅);
srs.CopyPixels(新Int32Rect(0,0,宽度,高度),PTR,高*步幅,步幅);
使用(VAR BTM =新System.Drawing.Bitmap(宽度,高度,跨度,System.Drawing.Imaging.PixelFormat.Format1bppIndexed,PTR))
{
//克隆位图,使我们可以处理它,
//释放在PTR的非托管内存
返回新System.Drawing.Bitmap(BTM);
}
}
最后
{
如果(PTR!= IntPtr.Zero)
Marshal.FreeHGlobal(PTR);
}
}
I've found loads of people converting BitmapSources to Bitmaps, but what about ImageSources to Bitmaps? I am making an imaging program and I need to extract bitmaps from the image displayed in the Image element. Does anyone know how to do this?
EDIT 1:
This is a function for converting the Bitmap Image to a Bitmap. Remember to set the 'unsafe' option in the compiler preferences.
public static System.Drawing.Bitmap BitmapSourceToBitmap(BitmapSource srs)
{
System.Drawing.Bitmap btm = null;
int width = srs.PixelWidth;
int height = srs.PixelHeight;
int stride = width * ((srs.Format.BitsPerPixel + 7) / 8);
byte[] bits = new byte[height * stride];
srs.CopyPixels(bits, stride, 0);
unsafe
{
fixed (byte* pB = bits)
{
IntPtr ptr = new IntPtr(pB);
btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr);
}
}
return btm;
}
Next is now to get a Bitmap Image:
RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
(int)inkCanvas1.ActualWidth,
(int)inkCanvas1.ActualHeight,
96d, 96d,
PixelFormats.Default);
targetBitmap.Render(inkCanvas1);
MemoryStream mse = new MemoryStream();
System.Windows.Media.Imaging.BmpBitmapEncoder mem = new BmpBitmapEncoder();
mem.Frames.Add(BitmapFrame.Create(targetBitmap));
mem.Save(mse);
mse.Position = 0;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = mse;
bi.EndInit();
Next is to convert it:
Bitmap b = new Bitmap(BitmapSourceToBitmap(bi));
Actually you don't need to use unsafe code. There's an overload of CopyPixels
that accepts an IntPtr:
public static System.Drawing.Bitmap BitmapSourceToBitmap2(BitmapSource srs)
{
int width = srs.PixelWidth;
int height = srs.PixelHeight;
int stride = width * ((srs.Format.BitsPerPixel + 7) / 8);
IntPtr ptr = IntPtr.Zero;
try
{
ptr = Marshal.AllocHGlobal(height * stride);
srs.CopyPixels(new Int32Rect(0, 0, width, height), ptr, height * stride, stride);
using (var btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr))
{
// Clone the bitmap so that we can dispose it and
// release the unmanaged memory at ptr
return new System.Drawing.Bitmap(btm);
}
}
finally
{
if (ptr != IntPtr.Zero)
Marshal.FreeHGlobal(ptr);
}
}
这篇关于C# - 转换WPF Image.source到System.Drawing.Bitmap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!