将 MagickImage 转换为位图
Convert MagickImage to bitmap
我以为这会更容易,但我找不到办法。如何将 MagickImage 转换为 System.Drawing.Image(例如位图)
public System.Drawing.Image CreateThumbnailIcon(string sourceImagePath, int iconSize )
{
MagickImage image = new MagickImage(sourceImagePath);
MagickGeometry geometry = new MagickGeometry(iconSize, iconSize);
image.Resize(geometry);
return image.??????;
}
对于网络框架,您可以使用 ToBitmap
扩展 method
对于 net core / net5+ - 没有开箱即用的方法,Magick.NET 的作者只是说“不要在新代码中使用 System.Drawing
”。
但是,如果你真的需要这个,你可以使用来自相应 GitHub issue
的 extension methods
public enum BitmapDensity
{
/// <summary>
/// Ignore the density of the image when creating the bitmap.
/// </summary>
Ignore,
/// <summary>
/// Use the density of the image when creating the bitmap.
/// </summary>
Use,
}
public static class MagickImageExtensions
{
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive.")]
public static Bitmap ToBitmap(this MagickImage imageMagick, BitmapDensity bitmapDensity)
{
string mapping = "BGR";
var format = PixelFormat.Format24bppRgb;
var image = imageMagick;
try
{
if( image.ColorSpace != ColorSpace.sRGB )
{
image = (MagickImage)imageMagick.Clone();
image.ColorSpace = ColorSpace.sRGB;
}
if( image.HasAlpha )
{
mapping = "BGRA";
format = PixelFormat.Format32bppArgb;
}
using( IPixelCollection pixels = image.GetPixelsUnsafe() )
{
var bitmap = new Bitmap(image.Width, image.Height, format);
var data = bitmap.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, format);
var destination = data.Scan0;
for( int y = 0; y < image.Height; y++ )
{
byte[] bytes = pixels.ToByteArray(0, y, image.Width, 1, mapping);
Marshal.Copy(bytes, 0, destination, bytes.Length);
destination = new IntPtr(destination.ToInt64() + data.Stride);
}
bitmap.UnlockBits(data);
SetBitmapDensity(imageMagick, bitmap, bitmapDensity);
return bitmap;
}
}
finally
{
if( ! ReferenceEquals(image, imageMagick) )
image.Dispose();
}
}
public static Bitmap ToBitmap(this MagickImage imageMagick) => ToBitmap(imageMagick, BitmapDensity.Ignore);
public static Bitmap ToBitmap(this MagickImage imageMagick, ImageFormat imageFormat) => ToBitmap(imageMagick, imageFormat, BitmapDensity.Ignore);
public static Bitmap ToBitmap(this MagickImage imageMagick, ImageFormat imageFormat, BitmapDensity bitmapDensity)
{
imageMagick.Format = InternalMagickFormatInfo.GetFormat(imageFormat);
MemoryStream memStream = new MemoryStream();
imageMagick.Write(memStream);
memStream.Position = 0;
/* Do not dispose the memStream, the bitmap owns it. */
var bitmap = new Bitmap(memStream);
SetBitmapDensity(imageMagick, bitmap, bitmapDensity);
return bitmap;
}
public static BitmapSource ToBitmapSource(this MagickImage imageMagick)
{
return ToBitmapSource(imageMagick, BitmapDensity.Ignore);
}
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive.")]
public static System.Windows.Media.Imaging.BitmapSource ToBitmapSource(this MagickImage imageMagick, BitmapDensity bitmapDensity)
{
IMagickImage image = imageMagick;
var mapping = "RGB";
var format = MediaPixelFormats.Rgb24;
try
{
if (imageMagick.ColorSpace == ColorSpace.CMYK && !image.HasAlpha)
{
mapping = "CMYK";
format = MediaPixelFormats.Cmyk32;
}
else
{
if (imageMagick.ColorSpace != ColorSpace.sRGB)
{
image = (MagickImage) imageMagick.Clone();
image.ColorSpace = ColorSpace.sRGB;
}
if (image.HasAlpha)
{
mapping = "BGRA";
format = MediaPixelFormats.Bgra32;
}
}
var step = format.BitsPerPixel / 8;
var stride = imageMagick.Width * step;
using (IPixelCollection pixels = image.GetPixelsUnsafe())
{
var bytes = pixels.ToByteArray(mapping);
var dpi = GetDpi(imageMagick, bitmapDensity);
return BitmapSource.Create(imageMagick.Width, imageMagick.Height, dpi.X, dpi.Y, format, null, bytes, stride);
}
}
finally
{
if (!ReferenceEquals(imageMagick, image))
image.Dispose();
}
}
public static void FromBitmap(this MagickImage imageMagick, Bitmap bitmap)
{
using (MemoryStream memStream = new MemoryStream())
{
if (IsSupportedImageFormat(bitmap.RawFormat))
bitmap.Save(memStream, bitmap.RawFormat);
else
bitmap.Save(memStream, ImageFormat.Bmp);
memStream.Position = 0;
imageMagick.Read(memStream);
}
}
private static bool IsSupportedImageFormat(ImageFormat format)
{
return
format.Guid.Equals(ImageFormat.Bmp.Guid) ||
format.Guid.Equals(ImageFormat.Gif.Guid) ||
format.Guid.Equals(ImageFormat.Icon.Guid) ||
format.Guid.Equals(ImageFormat.Jpeg.Guid) ||
format.Guid.Equals(ImageFormat.Png.Guid) ||
format.Guid.Equals(ImageFormat.Tiff.Guid);
}
private static void SetBitmapDensity(MagickImage imageMagick, Bitmap bitmap, BitmapDensity bitmapDensity)
{
if (bitmapDensity == BitmapDensity.Use)
{
var dpi = GetDpi(imageMagick, bitmapDensity);
bitmap.SetResolution((float)dpi.X, (float)dpi.Y);
}
}
private static Density GetDpi(MagickImage imageMagick, BitmapDensity bitmapDensity)
{
if (bitmapDensity == BitmapDensity.Ignore || (imageMagick.Density.Units == DensityUnit.Undefined && imageMagick.Density.X == 0 && imageMagick.Density.Y == 0))
return new Density(96);
return imageMagick.Density.ChangeUnits(DensityUnit.PixelsPerInch);
}
}
public class InternalMagickFormatInfo
{
internal static MagickFormat GetFormat(ImageFormat format)
{
if (format == ImageFormat.Bmp || format == ImageFormat.MemoryBmp)
return MagickFormat.Bmp;
else if (format == ImageFormat.Gif)
return MagickFormat.Gif;
else if (format == ImageFormat.Icon)
return MagickFormat.Icon;
else if (format == ImageFormat.Jpeg)
return MagickFormat.Jpeg;
else if (format == ImageFormat.Png)
return MagickFormat.Png;
else if (format == ImageFormat.Tiff)
return MagickFormat.Tiff;
else
throw new NotSupportedException("Unsupported image format: " + format.ToString());
}
}
}
我无法确认这是否有效,我是凭记忆做的,但请试一试:
MagickImage image = new MagickImage(sourceImagePath);
MagickGeometry geometry = new MagickGeometry(iconSize, iconSize);
image.Resize(geometry);
using (var memStream = new MemoryStream())
{
// Write the image to the memorystream
image.Write(memStream);
return new System.Drawing.Bitmap(memStream);
}
我以为这会更容易,但我找不到办法。如何将 MagickImage 转换为 System.Drawing.Image(例如位图)
public System.Drawing.Image CreateThumbnailIcon(string sourceImagePath, int iconSize )
{
MagickImage image = new MagickImage(sourceImagePath);
MagickGeometry geometry = new MagickGeometry(iconSize, iconSize);
image.Resize(geometry);
return image.??????;
}
对于网络框架,您可以使用 ToBitmap
扩展 method
对于 net core / net5+ - 没有开箱即用的方法,Magick.NET 的作者只是说“不要在新代码中使用 System.Drawing
”。
但是,如果你真的需要这个,你可以使用来自相应 GitHub issue
的 extension methods public enum BitmapDensity
{
/// <summary>
/// Ignore the density of the image when creating the bitmap.
/// </summary>
Ignore,
/// <summary>
/// Use the density of the image when creating the bitmap.
/// </summary>
Use,
}
public static class MagickImageExtensions
{
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive.")]
public static Bitmap ToBitmap(this MagickImage imageMagick, BitmapDensity bitmapDensity)
{
string mapping = "BGR";
var format = PixelFormat.Format24bppRgb;
var image = imageMagick;
try
{
if( image.ColorSpace != ColorSpace.sRGB )
{
image = (MagickImage)imageMagick.Clone();
image.ColorSpace = ColorSpace.sRGB;
}
if( image.HasAlpha )
{
mapping = "BGRA";
format = PixelFormat.Format32bppArgb;
}
using( IPixelCollection pixels = image.GetPixelsUnsafe() )
{
var bitmap = new Bitmap(image.Width, image.Height, format);
var data = bitmap.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, format);
var destination = data.Scan0;
for( int y = 0; y < image.Height; y++ )
{
byte[] bytes = pixels.ToByteArray(0, y, image.Width, 1, mapping);
Marshal.Copy(bytes, 0, destination, bytes.Length);
destination = new IntPtr(destination.ToInt64() + data.Stride);
}
bitmap.UnlockBits(data);
SetBitmapDensity(imageMagick, bitmap, bitmapDensity);
return bitmap;
}
}
finally
{
if( ! ReferenceEquals(image, imageMagick) )
image.Dispose();
}
}
public static Bitmap ToBitmap(this MagickImage imageMagick) => ToBitmap(imageMagick, BitmapDensity.Ignore);
public static Bitmap ToBitmap(this MagickImage imageMagick, ImageFormat imageFormat) => ToBitmap(imageMagick, imageFormat, BitmapDensity.Ignore);
public static Bitmap ToBitmap(this MagickImage imageMagick, ImageFormat imageFormat, BitmapDensity bitmapDensity)
{
imageMagick.Format = InternalMagickFormatInfo.GetFormat(imageFormat);
MemoryStream memStream = new MemoryStream();
imageMagick.Write(memStream);
memStream.Position = 0;
/* Do not dispose the memStream, the bitmap owns it. */
var bitmap = new Bitmap(memStream);
SetBitmapDensity(imageMagick, bitmap, bitmapDensity);
return bitmap;
}
public static BitmapSource ToBitmapSource(this MagickImage imageMagick)
{
return ToBitmapSource(imageMagick, BitmapDensity.Ignore);
}
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive.")]
public static System.Windows.Media.Imaging.BitmapSource ToBitmapSource(this MagickImage imageMagick, BitmapDensity bitmapDensity)
{
IMagickImage image = imageMagick;
var mapping = "RGB";
var format = MediaPixelFormats.Rgb24;
try
{
if (imageMagick.ColorSpace == ColorSpace.CMYK && !image.HasAlpha)
{
mapping = "CMYK";
format = MediaPixelFormats.Cmyk32;
}
else
{
if (imageMagick.ColorSpace != ColorSpace.sRGB)
{
image = (MagickImage) imageMagick.Clone();
image.ColorSpace = ColorSpace.sRGB;
}
if (image.HasAlpha)
{
mapping = "BGRA";
format = MediaPixelFormats.Bgra32;
}
}
var step = format.BitsPerPixel / 8;
var stride = imageMagick.Width * step;
using (IPixelCollection pixels = image.GetPixelsUnsafe())
{
var bytes = pixels.ToByteArray(mapping);
var dpi = GetDpi(imageMagick, bitmapDensity);
return BitmapSource.Create(imageMagick.Width, imageMagick.Height, dpi.X, dpi.Y, format, null, bytes, stride);
}
}
finally
{
if (!ReferenceEquals(imageMagick, image))
image.Dispose();
}
}
public static void FromBitmap(this MagickImage imageMagick, Bitmap bitmap)
{
using (MemoryStream memStream = new MemoryStream())
{
if (IsSupportedImageFormat(bitmap.RawFormat))
bitmap.Save(memStream, bitmap.RawFormat);
else
bitmap.Save(memStream, ImageFormat.Bmp);
memStream.Position = 0;
imageMagick.Read(memStream);
}
}
private static bool IsSupportedImageFormat(ImageFormat format)
{
return
format.Guid.Equals(ImageFormat.Bmp.Guid) ||
format.Guid.Equals(ImageFormat.Gif.Guid) ||
format.Guid.Equals(ImageFormat.Icon.Guid) ||
format.Guid.Equals(ImageFormat.Jpeg.Guid) ||
format.Guid.Equals(ImageFormat.Png.Guid) ||
format.Guid.Equals(ImageFormat.Tiff.Guid);
}
private static void SetBitmapDensity(MagickImage imageMagick, Bitmap bitmap, BitmapDensity bitmapDensity)
{
if (bitmapDensity == BitmapDensity.Use)
{
var dpi = GetDpi(imageMagick, bitmapDensity);
bitmap.SetResolution((float)dpi.X, (float)dpi.Y);
}
}
private static Density GetDpi(MagickImage imageMagick, BitmapDensity bitmapDensity)
{
if (bitmapDensity == BitmapDensity.Ignore || (imageMagick.Density.Units == DensityUnit.Undefined && imageMagick.Density.X == 0 && imageMagick.Density.Y == 0))
return new Density(96);
return imageMagick.Density.ChangeUnits(DensityUnit.PixelsPerInch);
}
}
public class InternalMagickFormatInfo
{
internal static MagickFormat GetFormat(ImageFormat format)
{
if (format == ImageFormat.Bmp || format == ImageFormat.MemoryBmp)
return MagickFormat.Bmp;
else if (format == ImageFormat.Gif)
return MagickFormat.Gif;
else if (format == ImageFormat.Icon)
return MagickFormat.Icon;
else if (format == ImageFormat.Jpeg)
return MagickFormat.Jpeg;
else if (format == ImageFormat.Png)
return MagickFormat.Png;
else if (format == ImageFormat.Tiff)
return MagickFormat.Tiff;
else
throw new NotSupportedException("Unsupported image format: " + format.ToString());
}
}
}
我无法确认这是否有效,我是凭记忆做的,但请试一试:
MagickImage image = new MagickImage(sourceImagePath);
MagickGeometry geometry = new MagickGeometry(iconSize, iconSize);
image.Resize(geometry);
using (var memStream = new MemoryStream())
{
// Write the image to the memorystream
image.Write(memStream);
return new System.Drawing.Bitmap(memStream);
}