iron-software / IronSoftware.System.Drawing

An open-source System.Drawing.Common replacement for .NET 5 and above on all platforms. Bringing together System.Drawing, Maui, and ImageSharp's Bitmap, Image, Font, and Shape types via an agnostic free NuGet package.
Other
120 stars 19 forks source link

Is there any equivalent method of System.Drawing.Bitmap(int width, int height, int stride, System.Drawing.Imaging.PixelFormat format, System.IntPtr scan0) #22

Closed mail2mhossain closed 1 year ago

mail2mhossain commented 1 year ago

Is there any equivalent method of System.Drawing.Bitmap(int width, int height, int stride, System.Drawing.Imaging.PixelFormat format, System.IntPtr scan0) in IronSoftware.Drawing.AnyBitmap

michael-ironsoftware commented 1 year ago

Hello mail2mhossain and thank you for the feature request.

Please try our latest version: v2022.12.11227 which contains the Scan0 function that you were inquiring about.

seealso: Scan0 property

mail2mhossain commented 1 year ago

Thank you very much for your great supports.

I am trying to convert from SIPSorceryMedia.Abstractions.RawImage to AnyBitmap.

It can be converted to System.Drawing.Bitmap as follows: System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(rawImage.Width, rawImage.Height, rawImage.Stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, rawImage.Sample);

Now I want to convert it to directly to AnyBitmap

SIPSorceryMedia.Abstractions.RawImage -> https://github.com/sipsorcery-org/SIPSorceryMedia.Abstractions/blob/master/src/MediaEndPoints.cs It has following properties:

  1. int Width
  2. int Height
  3. int Stride
  4. IntPtr Sample
  5. VideoPixelFormatsEnum PixelFormat -> https://github.com/sipsorcery-org/SIPSorceryMedia.Abstractions/blob/master/src/MediaEndPoints.cs

public enum VideoPixelFormatsEnum { Rgb, Bgr, Bgra, I420, NV12 }

mee-ironsoftware commented 1 year ago

Hello @mail2mhossain,

You can convert IntPtr into byte array.

byte[] managedArray = new byte[rawImage.Width * rawImage.Height * rawImage.Stride];
Marshal.Copy(rawImage.Sample, managedArray, 0, managedArray.Length);

// Then created AnyBitmap with byte array
AnyBitmap bmpImage = AnyBitmap.FromBytes(managedArray);

Hope this help.

mail2mhossain commented 1 year ago

Not working. I think bcoz of VideoPixelFormatsEnum.Rgb

mail2mhossain commented 1 year ago

RESPONSE FROM SIPSORCERY:

SIPSorceryMedia.Abstractions.RawImage contains all necessary info about an image in AV_PIX_FMT_BGR24 format (format in FFmpeg context)

So 8 bits for B, 8 bits for G, 8 bits for R (=> 24 bits for one pixel), it's size (width and height) and it's stride

As an example, This AV_PIX_FMT_BGR24 format is the same as this one PixelFormat.Format24bppRgb in System.Drawing.Imaging context.

According the library, you must use an equivalent:

use 8 bits for each colors no alpha necessary to specify width, height and stride

About stride, read this: https://learn.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.-ctor?view=dotnet-plat-ext-7.0#system-drawing-bitmap-ctor(system-int32-system-int32-system-int32-system-drawing-imaging-pixelformat-system-intptr)

mee-ironsoftware commented 1 year ago

If the image is RGB.

Please try

byte[] managedArray = new byte[rawImage.Width * rawImage.Height * 3];
Marshal.Copy(rawImage.Sample, managedArray, 0, managedArray.Length);

// Then created AnyBitmap with byte array
AnyBitmap bmpImage = AnyBitmap.FromBytes(managedArray);

Hope this help.

mail2mhossain commented 1 year ago

Not working.

Would you please go through RESPONSE FROM SIPSORCERY -> https://github.com/iron-software/IronSoftware.System.Drawing/issues/22#issuecomment-1367120414

mee-ironsoftware commented 1 year ago

The length of byte array should be [heigh * stride]. So please try,

byte[] managedArray = new byte[rawImage.Height * rawImage.Stride];
Marshal.Copy(rawImage.Sample, managedArray, 0, managedArray.Length);

// Then created AnyBitmap with byte array
AnyBitmap bmpImage = AnyBitmap.FromBytes(managedArray);

This problem is just converting an IntPtr of byte array into byte array. If it's not working, you may need to provide more info of your problem. Please not just tell us that it's not working without any information cause it's hard to guess.

mail2mhossain commented 1 year ago

Not getting any image.

When I am using: AnyBitmap bmpImage = new System.Drawing.Bitmap(rawImage.Width, rawImage.Height, rawImage.Stride, System.Drawing.Imaging.PixelFormat.Format24bppRgb, rawImage.Sample); getting an image.

BUT when i am using: byte[] managedArray = new byte[rawImage.Height * rawImage.Stride]; Marshal.Copy(rawImage.Sample, managedArray, 0, managedArray.Length); AnyBitmap bmpImage = AnyBitmap.FromBytes(managedArray); did not get any image.

I have uploaded a test project. In "videoSource_OnVideoSourceRawSampleFaster" method of class "VideoCaptureDevice" has image conversion code.

github link: https://github.com/mail2mhossain/RawImageToAnyBitmap.git PLEASE PUT "ffmpeg" folder under debug folder.