How to convert ImageSource to Byte array?

后端 未结 6 575
眼角桃花
眼角桃花 2020-11-30 14:20

I use LeadTools for scanning.

I want to convert scanning image to byte.

void twainSession_AcquirePage(object sender, TwainAcquirePageEventArgs e)
 {
         


        
相关标签:
6条回答
  • 2020-11-30 14:48

    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.

    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

    0 讨论(0)
  • 2020-11-30 14:53

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

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

       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

    0 讨论(0)
  • 2020-11-30 14:57

    If you are using Xamarin, you can use this:

    public byte[] ImageSourceToBytes(ImageSource imageSource)
    {
        StreamImageSource streamImageSource = (StreamImageSource)imageSource;
        System.Threading.CancellationToken cancellationToken = 
        System.Threading.CancellationToken.None;
        Task<Stream> task = streamImageSource.Stream(cancellationToken);
        Stream stream = task.Result;
        byte[] bytesAvailable = new byte[stream.Length];
        stream.Read(bytesAvailable, 0, bytesAvailable.Length);
        return bytesAvailable;
    }
    
    0 讨论(0)
  • 2020-11-30 14:58

    I use use a 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();
    }
    
    0 讨论(0)
  • 2020-11-30 15:10

    I use this class to work with Image in 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.

    0 讨论(0)
  • 2020-11-30 15:11

    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:

    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:

    RasterCodecs codecs = new RasterCodecs();
    System.IO.MemoryStream memStream = new System.IO.MemoryStream();
    codecs.Save(e.Image, memStream, RasterImageFormat.Jpeg, 24);
    
    0 讨论(0)
提交回复
热议问题