wpf 如何将 ImageSource 转换为 Byte 数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26814426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:41:09  来源:igfitidea点击:

How to convert ImageSource to Byte array?

c#wpfleadtools-sdk

提问by ar.gorgin

I use LeadTools for scanning.

我使用 LeadTools 进行扫描。

I want to convert scanning image to byte.

我想将扫描图像转换为字节。

void twainSession_AcquirePage(object sender, TwainAcquirePageEventArgs e)
 {
   ScanImage = e.Image.Clone();
   ImageSource source = RasterImageConverter.ConvertToSource(ScanImage, ConvertToSourceOptions.None);
 }

How to convert ImageSource to Byte array?

如何将 ImageSource 转换为 Byte 数组?

采纳答案by LEADTOOLS Support

Unless you explicitly need an ImageSource object, there's no need to convert to one. You can get a byte array containing the pixel data directly from Leadtools.RasterImage using this code:

除非您明确需要 ImageSource 对象,否则无需转换为一个对象。您可以使用以下代码直接从 Leadtools.RasterImage 获取包含像素数据的字节数组:

int totalPixelBytes = e.Image.BytesPerLine * e.Image.Height;
byte[] byteArray = new byte[totalPixelBytes];
e.Image.GetRow(0, byteArray, 0, totalPixelBytes);

Note that this gives you only the raw pixel data.

请注意,这仅提供原始像素数据。

If you need a memory stream or byte array that contains a complete image such as JPEG, you also do not need to convert to source. You can use the Leadtools.RasterCodecs class like this:

如果您需要包含完整图像(例如 JPEG)的内存流或字节数组,您也不需要转换为源。您可以像这样使用 Leadtools.RasterCodecs 类:

RasterCodecs codecs = new RasterCodecs();
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
codecs.Save(e.Image, memStream, RasterImageFormat.Jpeg, 24);

回答by Developer

I use this class to work with Imagein WPF

我使用这个类Image在 WPF 中使用

public static class ImageHelper
    {
        /// <summary>
        /// ImageSource to bytes
        /// </summary>
        /// <param name="encoder"></param>
        /// <param name="imageSource"></param>
        /// <returns></returns>
        public static byte[] ImageSourceToBytes(BitmapEncoder encoder, ImageSource imageSource)
        {
            byte[] bytes = null;
            var bitmapSource = imageSource as BitmapSource;

            if (bitmapSource != null)
            {
                encoder.Frames.Add(BitmapFrame.Create(bitmapSource));

                using (var stream = new MemoryStream())
                {
                    encoder.Save(stream);
                    bytes = stream.ToArray();
                }
            }

            return bytes;
        }

        [DllImport("gdi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DeleteObject(IntPtr value);

        public static BitmapSource GetImageStream(Image myImage)
        {
            var bitmap = new Bitmap(myImage);
            IntPtr bmpPt = bitmap.GetHbitmap();
            BitmapSource bitmapSource =
             System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                   bmpPt,
                   IntPtr.Zero,
                   Int32Rect.Empty,
                   BitmapSizeOptions.FromEmptyOptions());

            //freeze bitmapSource and clear memory to avoid memory leaks
            bitmapSource.Freeze();
            DeleteObject(bmpPt);

            return bitmapSource;
        }

        /// <summary>
        /// Convert String to ImageFormat
        /// </summary>
        /// <param name="format"></param>
        /// <returns></returns>
        public static System.Drawing.Imaging.ImageFormat ImageFormatFromString(string format)
        {
            if (format.Equals("Jpg"))
                format = "Jpeg";
            Type type = typeof(System.Drawing.Imaging.ImageFormat);
            BindingFlags flags = BindingFlags.GetProperty;
            object o = type.InvokeMember(format, flags, null, type, null);
            return (System.Drawing.Imaging.ImageFormat)o;
        }

        /// <summary>
        /// Read image from path
        /// </summary>
        /// <param name="imageFile"></param>
        /// <param name="imageFormat"></param>
        /// <returns></returns>
        public static byte[] BytesFromImage(String imageFile, System.Drawing.Imaging.ImageFormat imageFormat)
        {
            MemoryStream ms = new MemoryStream();
            Image img = Image.FromFile(imageFile);
            img.Save(ms, imageFormat);
            return ms.ToArray();
        }

        /// <summary>
        /// Convert image to byte array
        /// </summary>
        /// <param name="imageIn"></param>
        /// <param name="imageFormat"></param>
        /// <returns></returns>
        public static byte[] ImageToByteArray(System.Drawing.Image imageIn, System.Drawing.Imaging.ImageFormat imageFormat)
        {
            MemoryStream ms = new MemoryStream();
            imageIn.Save(ms, imageFormat);
            return ms.ToArray();
        }

        /// <summary>
        /// Byte array to photo
        /// </summary>
        /// <param name="byteArrayIn"></param>
        /// <returns></returns>
        public static Image ByteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }
    }

So try different approaches and modernize this class as you need.

因此,尝试不同的方法并根据需要对此类进行现代化改造。

回答by Alireza Sattari

I ran into this issue in Xamarin.Forms where I needed to convert a taken photo from the camera into a Byte array. After spending days trying to find out how, I saw this solution in the Xamarin forums.

我在 Xamarin.Forms 中遇到了这个问题,我需要将相机拍摄的照片转换为 Byte 数组。在花了几天时间试图找出方法之后,我在 Xamarin 论坛中看到了这个解决方案。

var photo = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions() { });

byte[] imageArray = null;

using (MemoryStream memory = new MemoryStream()) {

    Stream stream = photo.GetStream();
    stream.CopyTo(memory);
    imageArray = memory.ToArray();
}


Source: https://forums.xamarin.com/discussion/156236/how-to-get-the-bytes-from-the-imagesource-in-xamarin-forms


来源:https: //forums.xamarin.com/discussion/156236/how-to-get-the-bytes-from-the-imagesource-in-xamarin-forms

回答by Eric

It seems that you can cast the result from .ConvertToSource to a BitmapSource instead of a ImageSource.

似乎您可以将结果从 .ConvertToSource 转换为 BitmapSource 而不是 ImageSource。

I am not 100% sure how this translate to your case but the doc from LeadTools show this VB sample:

我不是 100% 确定这如何转化为您的案例,但 LeadTools 的文档显示了这个 VB 示例:

   Dim source As BitmapSource
   Using raster As RasterImage = RasterImageConverter.ConvertFromSource(bitmap, ConvertFromSourceOptions.None)
      Console.WriteLine("Converted to RasterImage, bits/pixel is {0} and order is {1}", raster.BitsPerPixel, raster.Order)

      ' Perform image processing on the raster image using LEADTOOLS
      Dim cmd As New FlipCommand(False)
      cmd.Run(raster)

      ' Convert the image back to WPF using default options
      source = DirectCast(RasterImageConverter.ConvertToSource(raster, ConvertToSourceOptions.None), BitmapSource)
   End Using

I think it should be like

我认为它应该像

BitmapSource source = RasterImageConverter.ConvertToSource(ScanImage, ConvertToSourceOptions.None) as BitmapSource;

Then you can copy the BitmapSource pixels with BitmapSource.CopyPixels

然后你可以用BitmapSource.CopyPixels复制 BitmapSource 像素

回答by ar.gorgin

I use use a MemoryStream:

我使用 MemoryStream:

var source = RasterImageConverter.ConvertToSource(ScanImage, ConvertToSourceOptions.None) as BitmapSource;
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(source));
using (MemoryStream ms = new MemoryStream())
{
   encoder.Save(ms);
   data = ms.ToArray();
}