Converting .NET Bitmap to GDAL Dataset

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Converting .NET Bitmap to GDAL Dataset

Maksim Sestic
Hi all,

Is there any example (or a hint) of converting a System.Drawing.Bitmap into
GDAL Dataset?

Regards,
Maksim Sestic
Reply | Threaded
Open this post in threaded view
|

[gdal-dev] Converting .NET Bitmap to GDAL Dataset

Tamas Szekeres

For an example of the reverse action see SaveBitMapDirect in GDALReadDirect.cs 
To write data to GDAL dataset see: GDALWrite.cs or GDALDatasetWrite.cs

Best regards,

Tamas



2013/3/22 Maksim Sestic <[hidden email]>
Hi all,

Is there any example (or a hint) of converting a System.Drawing.Bitmap into
GDAL Dataset?

Regards,
Maksim Sestic



--
View this message in context: http://osgeo-org.1560.n6.nabble.com/Converting-NET-Bitmap-to-GDAL-Dataset-tp5042430.html
Sent from the GDAL - Dev mailing list archive at Nabble.com.
_______________________________________________
gdal-dev mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/gdal-dev



_______________________________________________
gdal-dev mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/gdal-dev
Reply | Threaded
Open this post in threaded view
|

Re: Converting .NET Bitmap to GDAL Dataset

Tamas Szekeres
This is because there's no driver to recognise the image data directly. You should provide the image file in a GDAL supported binary format (like jpg or png or tif) or use the MEM driver to represent the dataset. I've created a new sample for this approach at:


In this example I create the bands in a reverse order as it looks like the Windows bitmap format requires it.


Best regards,

Tamas
 


2013/3/23 Maksim Sestic <[hidden email]>

It's a Bitmap instance created using:

 

Dim bmp As Bitmap = Bitmap.FromFile("C:\Input.png")

 

then converted to byte array (as per MSDN article):

 

' Lock the bitmap's bits.

Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)

Dim bmpData As BitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat)

 

' Get the address of the first line.

Dim ptr As IntPtr = bmpData.Scan0

 

' Declare an array to hold the bytes of the bitmap.

Dim bitmapData As Byte()

ReDim bitmapData(Math.Abs(bmpData.Stride) * bmp.Height)

 

' Copy the RGB values into the array.

Marshal.Copy(ptr, bitmapData, 0, bitmapData.Length)

 

' Unlock the bits.

bmp.UnlockBits(bmpData)

 

The rest is your code (abbreviated version):

 

'Code provided by Tamas Szekeres

Gdal.AllRegister()

Dim handle As GCHandle = GCHandle.Alloc(bitmapData, GCHandleType.Pinned)

Dim memFilename As String = "/vsimem/inmemfile"

Gdal.FileFromMemBuffer(memFilename, bitmapData.Length, handle.AddrOfPinnedObject())

Dim ds As Dataset = Gdal.Open(memFilename, Access.GA_ReadOnly)     '<<< Exception gets thrown at this line

Dim drv As Driver = Gdal.GetDriverByName("GTiff")

drv.CreateCopy("C:\Output.tif", ds, 0, Nothing, Nothing, Nothing)

Gdal.Unlink(memFilename)

handle.Free()

 

Sorry about my VB.NET :-)

 

I'm certain it's not about assembly referencing issues and such, since it works correctly using "classic" Gdal.Open(...) method.

 

Regards,

Maksim Sestic

 

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Saturday, March 23, 2013 23:46


To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

What is the input file you are using?

 

Tamas

 

2013/3/23 Maksim Sestic <[hidden email]>

Hi Tamas,

 

It throws exception at line:

 

Dataset ds = Gdal.Open(memFilename, Access.GA_ReadOnly);

 

...saying that "/vsimem/inmemfile" is not a recognized format.

 

I'm using GDAL 1.8.0, could it be version-related?

 

Regards,

Maksim Sestic

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Saturday, March 23, 2013 22:11


To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

Added a C# example to demonstrate the usage of the /vsimem facilities.

 

 

Best regards,

 

Tamas

 

 

 

2013/3/23 Maksim Sestic <[hidden email]>

Hi Tamas,

 

Thanks for the help. I recall hitting this issue before as well: http://lists.osgeo.org/pipermail/gdal-dev/2012-May/032972.html

 

Regards,

Maksim Sestic

 

P.S.

Sorry, just noticed that the conversation went to priv. only and not to gdal-dev forum.

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Saturday, March 23, 2013 10:56


To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

You may probably utilize the MEM driver (http://www.gdal.org/frmt_mem.html) or the vsimem virtual file system http://gdal.org/cpl__vsi_8h.html#a66e2e6f093fd42f8a941b962d4c8a19e

 

Best regards,

 

Tamas

 

2013/3/22 Maksim Sestic <[hidden email]>

Hi Tamas,

 

You're right, thanks.

 

I was trying to create a pair of "roundtrip" classes utilizing Gdal. First one would read e.g. a file into Bitmap instance, that's what GDALRead.cs demonstrates perfectly. The other would write this Bitmap instance using Gdal drivers back to e.g. another file. You might have guessed that I was stuck at the second one. I neve actually coded against Gdal memory driver, should give it a try I guess...

 

Regards,

Maksim Sestic

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Friday, March 22, 2013 22:58
To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

Dataset is considered as an interface to the underlying driver. Aside from the 'in memory driver' and some sort of internal caching facilities the dataset doesn't hold data in memory. In this regard we cannot convert these 2 objects types to each other. The most obvious action regarding to your requirement is to create and in memory dataset and copy data from the bitmap to the dataset, as I've mentioned before.

 

Best regards,

 

Tamas

 

 

2013/3/22 Maksim Sestic <[hidden email]>

Hi Tamas,

 

If I'm not mistaken, GDALWrite.cs and GDALDatasetWrite.cs examples are about writing (using Create() method) a dataset to disk. What I'm trying to do is to convert a System.Drawing.Bitmap instance to a GDAL.Dataset, in-memory only. But I'm not sure about how to do it...

 

Regards,

Maksim Sestic

 

 


From: [hidden email] [mailto:[hidden email]] On Behalf Of Tamas Szekeres
Sent: Friday, March 22, 2013 21:12
To: gdal-dev
Subject: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

 

For an example of the reverse action see SaveBitMapDirect in GDALReadDirect.cs 

To write data to GDAL dataset see: GDALWrite.cs or GDALDatasetWrite.cs

 

Best regards,

 

Tamas

 

 

2013/3/22 Maksim Sestic <[hidden email]>

Hi all,

Is there any example (or a hint) of converting a System.Drawing.Bitmap into
GDAL Dataset?

Regards,
Maksim Sestic



--
View this message in context: http://osgeo-org.1560.n6.nabble.com/Converting-NET-Bitmap-to-GDAL-Dataset-tp5042430.html
Sent from the GDAL - Dev mailing list archive at Nabble.com.
_______________________________________________
gdal-dev mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/gdal-dev

 

 

 

 

 

 



_______________________________________________
gdal-dev mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/gdal-dev
Reply | Threaded
Open this post in threaded view
|

Re: Converting .NET Bitmap to GDAL Dataset

Tamas Szekeres
We could also convert the bitmap to png or some other formats that the GDAL drivers reconise, something like:

        byte[] imageBuffer;
        using (MemoryStream stream = new MemoryStream())
        {
            bmp.Save(stream, ImageFormat.Png);
            imageBuffer = stream.ToArray();
        }

        Gdal.FileFromMemBuffer(memFilename, imageBuffer);
        Dataset ds = Gdal.Open(memFilename, Access.GA_ReadOnly);


Best regards,

Tamas



2013/3/24 Tamas Szekeres <[hidden email]>
This is because there's no driver to recognise the image data directly. You should provide the image file in a GDAL supported binary format (like jpg or png or tif) or use the MEM driver to represent the dataset. I've created a new sample for this approach at:


In this example I create the bands in a reverse order as it looks like the Windows bitmap format requires it.


Best regards,

Tamas
 


2013/3/23 Maksim Sestic <[hidden email]>

It's a Bitmap instance created using:

 

Dim bmp As Bitmap = Bitmap.FromFile("C:\Input.png")

 

then converted to byte array (as per MSDN article):

 

' Lock the bitmap's bits.

Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)

Dim bmpData As BitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat)

 

' Get the address of the first line.

Dim ptr As IntPtr = bmpData.Scan0

 

' Declare an array to hold the bytes of the bitmap.

Dim bitmapData As Byte()

ReDim bitmapData(Math.Abs(bmpData.Stride) * bmp.Height)

 

' Copy the RGB values into the array.

Marshal.Copy(ptr, bitmapData, 0, bitmapData.Length)

 

' Unlock the bits.

bmp.UnlockBits(bmpData)

 

The rest is your code (abbreviated version):

 

'Code provided by Tamas Szekeres

Gdal.AllRegister()

Dim handle As GCHandle = GCHandle.Alloc(bitmapData, GCHandleType.Pinned)

Dim memFilename As String = "/vsimem/inmemfile"

Gdal.FileFromMemBuffer(memFilename, bitmapData.Length, handle.AddrOfPinnedObject())

Dim ds As Dataset = Gdal.Open(memFilename, Access.GA_ReadOnly)     '<<< Exception gets thrown at this line

Dim drv As Driver = Gdal.GetDriverByName("GTiff")

drv.CreateCopy("C:\Output.tif", ds, 0, Nothing, Nothing, Nothing)

Gdal.Unlink(memFilename)

handle.Free()

 

Sorry about my VB.NET :-)

 

I'm certain it's not about assembly referencing issues and such, since it works correctly using "classic" Gdal.Open(...) method.

 

Regards,

Maksim Sestic

 

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Saturday, March 23, 2013 23:46


To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

What is the input file you are using?

 

Tamas

 

2013/3/23 Maksim Sestic <[hidden email]>

Hi Tamas,

 

It throws exception at line:

 

Dataset ds = Gdal.Open(memFilename, Access.GA_ReadOnly);

 

...saying that "/vsimem/inmemfile" is not a recognized format.

 

I'm using GDAL 1.8.0, could it be version-related?

 

Regards,

Maksim Sestic

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Saturday, March 23, 2013 22:11


To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

Added a C# example to demonstrate the usage of the /vsimem facilities.

 

 

Best regards,

 

Tamas

 

 

 

2013/3/23 Maksim Sestic <[hidden email]>

Hi Tamas,

 

Thanks for the help. I recall hitting this issue before as well: http://lists.osgeo.org/pipermail/gdal-dev/2012-May/032972.html

 

Regards,

Maksim Sestic

 

P.S.

Sorry, just noticed that the conversation went to priv. only and not to gdal-dev forum.

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Saturday, March 23, 2013 10:56


To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

You may probably utilize the MEM driver (http://www.gdal.org/frmt_mem.html) or the vsimem virtual file system http://gdal.org/cpl__vsi_8h.html#a66e2e6f093fd42f8a941b962d4c8a19e

 

Best regards,

 

Tamas

 

2013/3/22 Maksim Sestic <[hidden email]>

Hi Tamas,

 

You're right, thanks.

 

I was trying to create a pair of "roundtrip" classes utilizing Gdal. First one would read e.g. a file into Bitmap instance, that's what GDALRead.cs demonstrates perfectly. The other would write this Bitmap instance using Gdal drivers back to e.g. another file. You might have guessed that I was stuck at the second one. I neve actually coded against Gdal memory driver, should give it a try I guess...

 

Regards,

Maksim Sestic

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Friday, March 22, 2013 22:58
To: Maksim Sestic
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

Dataset is considered as an interface to the underlying driver. Aside from the 'in memory driver' and some sort of internal caching facilities the dataset doesn't hold data in memory. In this regard we cannot convert these 2 objects types to each other. The most obvious action regarding to your requirement is to create and in memory dataset and copy data from the bitmap to the dataset, as I've mentioned before.

 

Best regards,

 

Tamas

 

 

2013/3/22 Maksim Sestic <[hidden email]>

Hi Tamas,

 

If I'm not mistaken, GDALWrite.cs and GDALDatasetWrite.cs examples are about writing (using Create() method) a dataset to disk. What I'm trying to do is to convert a System.Drawing.Bitmap instance to a GDAL.Dataset, in-memory only. But I'm not sure about how to do it...

 

Regards,

Maksim Sestic

 

 


From: [hidden email] [mailto:[hidden email]] On Behalf Of Tamas Szekeres
Sent: Friday, March 22, 2013 21:12
To: gdal-dev
Subject: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

 

For an example of the reverse action see SaveBitMapDirect in GDALReadDirect.cs 

To write data to GDAL dataset see: GDALWrite.cs or GDALDatasetWrite.cs

 

Best regards,

 

Tamas

 

 

2013/3/22 Maksim Sestic <[hidden email]>

Hi all,

Is there any example (or a hint) of converting a System.Drawing.Bitmap into
GDAL Dataset?

Regards,
Maksim Sestic



--
View this message in context: http://osgeo-org.1560.n6.nabble.com/Converting-NET-Bitmap-to-GDAL-Dataset-tp5042430.html
Sent from the GDAL - Dev mailing list archive at Nabble.com.
_______________________________________________
gdal-dev mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/gdal-dev

 

 

 

 

 

 




_______________________________________________
gdal-dev mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/gdal-dev
Reply | Threaded
Open this post in threaded view
|

Re: Converting .NET Bitmap to GDAL Dataset

Maksim Sestic

Hi Tamas,

 

Yes, finally, "vsimem" works once bitmap is Png (abbreviated VB.NET code follows):

 

      Dim bmp As Bitmap = Bitmap.FromFile("C:\Input.tif")

 

            Dim imageBuffer As Byte()

            Using stream As New MemoryStream()

                bmp.Save(stream, ImageFormat.Png)

                imageBuffer = stream.ToArray()

            End Using

 

            Dim pinnedArray As GCHandle = GCHandle.Alloc(imageBuffer, GCHandleType.Pinned)

            Dim pointer As IntPtr = pinnedArray.AddrOfPinnedObject()

 

            Dim memFilename As String = "/vsimem/data"

            Gdal.FileFromMemBuffer(memFilename, imageBuffer.Length, pointer)

            Dim ds As Dataset = Gdal.Open(memFilename, Access.GA_ReadOnly)

 

            Dim drv As Driver = Gdal.GetDriverByName("GTiff")

            Dim ds1 = drv.CreateCopy("C:\Output.tif", ds, 0, Nothing, Nothing, Nothing)

 

            pinnedArray.Free()

 

I've tested it on bitmaps originating from .bmp, .png, .tif and .jpg.

 

Regards,

Maksim Sestic

 


From: Tamas Szekeres [mailto:[hidden email]]
Sent: Sunday, March 24, 2013 17:25
To: Maksim Sestic
Cc: gdal-dev
Subject: Re: [gdal-dev] Converting .NET Bitmap to GDAL Dataset

 

We could also convert the bitmap to png or some other formats that the GDAL drivers reconise, something like:

 

        byte[] imageBuffer;

        using (MemoryStream stream = new MemoryStream())

        {

            bmp.Save(stream, ImageFormat.Png);

            imageBuffer = stream.ToArray();

        }

 

        Gdal.FileFromMemBuffer(memFilename, imageBuffer);

        Dataset ds = Gdal.Open(memFilename, Access.GA_ReadOnly);

 

 

Best regards,

 

Tamas


_______________________________________________
gdal-dev mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/gdal-dev