Aurigma Forums
»
Legacy Products
»
Archive
»
Other Products
»
How to pass Graphics Mill Bitmap data into System.Drawing.Bitmap object in .NET
Rank: Advanced Member
Groups: Member, Administration, Moderator Joined: 7/28/2003(UTC) Posts: 1,660
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
When you use Graphics Mill in .NET sometimes there is need to pass data into System.Drawing.Bitmap object. You can do it with following code without copying of data: Code: Dim GmBitmap As GraphicsMill.Bitmap
GmBitmap = AxBitmapViewer1.Bitmap
'Convert GmBitmap.Data.PixelFormat type into System.Drawing.Imaging.PixelFormat
'Pixel format in Graphics Mill is superset of System.Drawing.Imaging.PixelFormat
'We need to remove some bit flags from numeric value of current pixel format
'using multiplying with &HBFFFFF
Dim pf As System.Drawing.Imaging.PixelFormat = _
System.Enum.Parse(GetType(Drawing.Imaging.PixelFormat), GmBitmap.Data.PixelFormat And &HBFFFFF)
'Check if pixel format is supported by GDI+
If Not System.Enum.IsDefined(GetType(Drawing.Imaging.PixelFormat), pf) Then
GmBitmap.Data.ConvertTo32bppArgb(255, False)
pf = Drawing.Imaging.PixelFormat.Format32bppArgb
End If
'Create System.Drawing.Bitmap on Graphics Mill Bitmap data without copying
Dim GdiplusBitmap As New Bitmap(GmBitmap.Data.Width, GmBitmap.Data.Height, GmBitmap.Data.Stride, _
pf, New IntPtr(GmBitmap.Data.Scan0))
GdiplusBitmap.Save("c:\test3.jpg")
You should be very carefull with lifetime of System.Drawing.Bitmap object as it uses data of Graphics Mill Bitmap object. System.Drawing.Bitmap should be disposed always before releasing of Graphics Mill Bitmap or channging data in it. Edited by user Thursday, December 20, 2007 7:06:15 PM(UTC)
| Reason: Not specified |
Best regards, Fedor Skvortsov
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration, Moderator Joined: 7/28/2003(UTC) Posts: 1,660
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
Here is sample how to convert GDI+ bitmap to Graphics Mill Bitmap: Code: Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDst As IntPtr, _
ByVal pSrc As IntPtr, _
ByVal ByteLen As Long)
Public Function GdiplusBitmapToGmBitmap(ByVal GdiplusBitmap As System.Drawing.Bitmap) As Aurigma.GraphicsMill.Bitmap
Dim pf As Aurigma.GraphicsMill.PixelFormat
If GdiplusBitmap.PixelFormat = System.Drawing.Imaging.PixelFormat.Format24bppRgb Then
pf = Aurigma.GraphicsMill.PixelFormat.Format24bppRgb
ElseIf GdiplusBitmap.PixelFormat = System.Drawing.Imaging.PixelFormat.Format32bppRgb Then
pf = Aurigma.GraphicsMill.PixelFormat.Format32bppRgb
Else
Throw New Exception("Incompatible pixel format.")
End If
Dim GmBitmap As New Aurigma.GraphicsMill.Bitmap
GmBitmap.CreateNew(GdiplusBitmap.Width, GdiplusBitmap.Height, pf, &HFFFFFFFF, Nothing)
Dim bd As System.Drawing.Imaging.BitmapData = GdiplusBitmap.LockBits( _
New System.Drawing.Rectangle(0, 0, GdiplusBitmap.Width, GdiplusBitmap.Height), _
System.Drawing.Imaging.ImageLockMode.ReadOnly, GdiplusBitmap.PixelFormat)
CopyMemory(New IntPtr(GmBitmap.Data.Scan0), bd.Scan0, bd.Stride * bd.Height)
GdiplusBitmap.UnlockBits(bd)
Return GmBitmap
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim GdiplusBitmap As New System.Drawing.Bitmap("C:\Test.bmp")
Dim GmBitmap As Aurigma.GraphicsMill.Bitmap = GdiplusBitmapToGmBitmap(GdiplusBitmap)
GmBitmap.SaveToFile("C:\Result.bmp")
End Sub
Edited by user Thursday, December 20, 2007 7:06:27 PM(UTC)
| Reason: Not specified |
Best regards, Fedor Skvortsov
|
|
|
|
Rank: Member
Groups: Member
Joined: 4/27/2004(UTC) Posts: 40
|
I using the following code to do the transformation in c#: Code:// bmpFloor is an .net bmp object
// create the new aurigma bitmap
Aurigma.GraphicsMill.BitmapClass gmFloor = new Aurigma.GraphicsMill.BitmapClass();
// copy the info
MemoryStream memStream = new MemoryStream();
bmpFloor.Save( memStream, System.Drawing.Imaging.ImageFormat.Jpeg );
gmFloor.LoadFromMemory(memStream.GetBuffer());
// dont need the floor ms-bmp anymore
bmpFloor.Dispose();
Comments? Edited by user Thursday, December 20, 2007 7:06:57 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration, Moderator Joined: 7/28/2003(UTC) Posts: 1,660
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
On following line of code we recompress image to JPEG with loosing quality: Code:bmpFloor.Save( memStream, System.Drawing.Imaging.ImageFormat.Jpeg );
To avoid it we need to use lossless BMP or PNG formats: Code:bmpFloor.Save( memStream, System.Drawing.Imaging.ImageFormat.Bmp );
or Code:bmpFloor.Save( memStream, System.Drawing.Imaging.ImageFormat.Png );
Edited by user Thursday, December 20, 2007 7:07:18 PM(UTC)
| Reason: Not specified |
Best regards, Fedor Skvortsov
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
Besides of that, version posted by Fedor will work faster as there is no encoding to any file format at all and memory is not copied.
|
|
|
|
Rank: Member
Groups: Member
Joined: 4/27/2004(UTC) Posts: 40
|
Isn't memory copied by the CopyMemory function? It looks like you are copying the memory assigned to the bitmap's data into the newly aurigma bitmap's data.
Could you provide an example in C# ?
Thanks, Brian
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
Oops, I mixed it with the first sample (Graphics Mill -> GDI+)... :) However anyway, encoding to some file format takes extra time (depending on compression) which you need not to waste. If you saved to BMP (no compression), the overhead would be minimal, but I you can avoid overhead at all. The following C# code does the same. Do not forget add Code:using System.Runtime.InteropServices;
to get DllImport working. Code:
[DllImport("kernel32.dll")]
static extern void CopyMemory(System.IntPtr pDest, System.IntPtr pSrc, long byteLength);
private GraphicsMill.IBitmap GdiplusBitmapToGmBitmap(System.Drawing.Bitmap gdiplusBitmap)
{
// Convert GDI+ pixel format value to Graphics Mill pixel format
GraphicsMill.PixelFormat pf;
switch (gdiplusBitmap.PixelFormat)
{
case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
pf = GraphicsMill.PixelFormat.Format24bppRgb;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
pf = GraphicsMill.PixelFormat.Format32bppArgb;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
pf = GraphicsMill.PixelFormat.Format32bppRgb;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppPArgb:
pf = GraphicsMill.PixelFormat.Format32bppPArgb;
break;
default:
throw new System.Exception("Incompatible pixel format");
}
// Create new empty bitmap
GraphicsMill.IBitmap gmBitmap = new GraphicsMill.BitmapClass();
gmBitmap.CreateNew(gdiplusBitmap.Width, gdiplusBitmap.Height, pf, GraphicsMill.GraphicsMillConstants.ColorWhite, null);
System.Drawing.Imaging.BitmapData bitmapData;
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, gdiplusBitmap.Width, gdiplusBitmap.Height);
bitmapData = gdiplusBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, gdiplusBitmap.PixelFormat);
CopyMemory(new IntPtr(gmBitmap.Data.Scan0), bitmapData.Scan0, bitmapData.Stride * bitmapData.Height);
gdiplusBitmap.UnlockBits(bitmapData);
return gmBitmap;
}
private void button1_Click(object sender, System.EventArgs e)
{
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(@"D:\[Test Files]\Pictures\Blue hills.bmp");
GraphicsMill.IBitmap gmBitmap = GdiplusBitmapToGmBitmap(bmp);
gmBitmap.SaveToFile(@"d:\csharp.jpg");
}
Hope this helps. Edited by user Thursday, December 20, 2007 7:07:41 PM(UTC)
| Reason: Not specified
|
|
|
|
Rank: Member
Groups: Member
Joined: 4/27/2004(UTC) Posts: 40
|
Excellent - Thank You!
So there is a memory copy going on, but we are saving by doing it directly instead via any conversions.
What is the difference between using IBitmap and BitmapClass? So far I've been using the BitmapClass object. Are there any savings to be had by using one instead of the other?
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration Joined: 8/2/2003(UTC) Posts: 876
Thanks: 2 times Was thanked: 27 time(s) in 27 post(s)
|
In .NET you can use BitmapClass only. IBitmap is an interface class (class without implementation) and BitmapClass is a common class which implements this interface. When you work with COM languages using interfaces is the single way to exchange objects between different components (so I used IBitmap in declarations by C++ habit), but in .NET you can always use native .NET classes...
Frankly speaking I am not quite understand why wrapper generator exposes any COM interfaces. It is possible actual if you are going to use your .NET classes in COM applications though...
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration, Moderator Joined: 7/28/2003(UTC) Posts: 1,660
Thanks: 5 times Was thanked: 76 time(s) in 74 post(s)
|
We have released Graphics Mill for .NET 3.0 which can be seamless integrated with GDI+ classes. Classes from System.Drawing and Aurigma.GraphicsMill can be casted each other. Also new Graphics Mill for .NET forum is available now. |
Best regards, Fedor Skvortsov
|
|
|
|
Rank: Member
Groups: Joined: 7/25/2007(UTC) Posts: 18
Thanks: 1 times
|
I'm trying to use GdiplusBitmapToGmBitmap () with Graphics Mill 4.0, but it looks like there were changes between 2.0 and 4.0, and it won't compile.
Could you post a version of GdiplusBitmapToGmBitmap () updated for Graphics Mill 4.0? Thanks!
|
|
|
|
Rank: Advanced Member
Groups: Member, Administration, Moderator Joined: 8/3/2003(UTC) Posts: 1,070
Thanks: 1 times Was thanked: 12 time(s) in 12 post(s)
|
Hello, It is very easy to convert System.Drawing.Bitmap instance to Aurigma.GraphicsMill.Bitmap one. To perform this you just should use Aurigma.GraphicsMill.Bitmap constructor. Edited by user Tuesday, January 1, 2008 4:40:45 AM(UTC)
| Reason: Not specified |
|
|
|
|
Aurigma Forums
»
Legacy Products
»
Archive
»
Other Products
»
How to pass Graphics Mill Bitmap data into System.Drawing.Bitmap object in .NET
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.