添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Author Topic: Direct Conversion of System.Drawing.Image to SFML.Graphics.Image  (Read 5780 times)

0 Members and 1 Guest are viewing this topic.

Well I've been through 4 versions so far and so bug out under some conditions for some unknown reason.  Other than that here's the code below. :)


Yes it's in C# but it shouldn't be hard to change up. :P
//http://stackoverflow.com/questions/7350679/convert-a-bitmap-into-a-byte-array-in-c
private static byte [ ] ImageToByteArray ( System. Drawing . Image resourceimage )
{
System. Drawing . ImageConverter imgcon = new System. Drawing . ImageConverter ( ) ;
return ( byte [ ] ) imgcon . ConvertTo ( resourceimage, typeof ( byte [ ] ) ) ;
}

// Yes Straight up C&P from here:
//http://social.msdn.microsoft.com/Forums/vstudio/en-US/47c5a003-1d26-4213-9370-fba3aa170c21/fastest-method-to-convert-bitmap-object-to-byte-array?forum=csharpgeneral
// A Case of either use full quantified names for SFML or C#. >.>
private static byte [ ] GetRGBValues ( System. Drawing . Bitmap bmp )
{

// Lock the bitmap's bits.
System. Drawing . Rectangle rect = new System. Drawing . Rectangle ( 0 , 0 , bmp . Width , bmp . Height ) ;
System. Drawing . Imaging . BitmapData bmpData = bmp . LockBits ( rect, System. Drawing . Imaging . ImageLockMode . ReadOnly , bmp . PixelFormat ) ;

// Get the address of the first line.
IntPtr ptr = bmpData . Scan0 ;

// Declare an array to hold the bytes of the bitmap.
int bytes = bmpData . Stride * bmp . Height ;
byte [ ] rgbValues = new byte [ bytes ] ;

// Copy the RGB values into the array.
System. Runtime . InteropServices . Marshal . Copy ( ptr, rgbValues, 0 , bytes ) ;
bmp . UnlockBits ( bmpData ) ;

return rgbValues ;
}
//http://www.sitepoint.com/forums/showthread.php?223894-Bitmap-to-byte-array-in-C
/*private static byte[] StreamImageToByteArray(System.Drawing.Image resourceimage)
{
MemoryStream stream = new MemoryStream();
resourceimage.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
//Byte[] bytes =
if (stream != null)
{
stream.Close();
}
return stream.ToArray();
}*/

//http://stackoverflow.com/questions/13602281/converting-bitmap-pixels-as-byte-array-fails
private static byte [ ] MarshalImageToByteArray ( System. Drawing . Bitmap bmp )
{
// Lock the bitmap's bits.
System. Drawing . Rectangle rect = new System. Drawing . Rectangle ( 0 , 0 , bmp . Width , bmp . Height ) ;
System. Drawing . Imaging . BitmapData bmpData = bmp . LockBits ( rect, System. Drawing . Imaging . ImageLockMode . ReadWrite , bmp . PixelFormat ) ;

// Get the address of the first line.
IntPtr ptr = bmpData . Scan0 ;

// Declare an array to hold the bytes of the bitmap.
int bytes = Math . Abs ( bmpData . Stride ) * bmp . Height ;
byte [ ] rgbValues = new byte [ bytes ] ;

// Copy the RGB values into the array.
System. Runtime . InteropServices . Marshal . Copy ( ptr, rgbValues, 0 , bytes ) ;
bmp . UnlockBits ( bmpData ) ;
return rgbValues ;
}

Here's both our solutions. :)


Quote from: StormWingDelta on April 06, 2014, 02:22:20 am
Here's My Solution.  Had to flip a few things for some odd reason but it works. :P


private SFML . Graphics . Image ToSFMLImage ( System. Drawing . Bitmap bmp )
{
SFML . Graphics . Color [ , ] sfmlcolorarray = new Color [ bmp . Height , bmp . Width ] ;
SFML . Graphics . Image newimage = null ;
for ( int x = 0 ; x < bmp . Width ; x ++ )
{
for ( int y = 0 ; y < bmp . Height ; y ++ )
{
System. Drawing . Color csharpcolor = bmp . GetPixel ( x, y ) ;
sfmlcolorarray [ y,x ] = new SFML . Graphics . Color ( csharpcolor . R , csharpcolor . G , csharpcolor . B , csharpcolor . A ) ;
}
}
newimage = new SFML . Graphics . Image ( sfmlcolorarray ) ;
return newimage ;
}

private SFML . Graphics . Texture ToSFMLTexture ( System. Drawing . Bitmap bmp )
{
return new Texture ( ToSFMLImage ( bmp ) ) ;
}
Do what you want with this... it only took me 10 minutes ;)

Yes the code is messy because I didn't bother to clean it up.
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
using System.Drawing ;
using SFML.Window ;
using SFML.Graphics ;
using System.IO ;

namespace WindowsFormsApplication2
{
static class Program
{

static void Main ( )
{
RenderWindow wind = new RenderWindow ( new VideoMode ( 500 , 500 ) , "Test" ) ;
wind . SetVerticalSyncEnabled ( true ) ;
Texture tx1 = new Texture ( "LBB.png" ) ;
Sprite sp1 = new Sprite ( tx1 ) { Scale = new Vector2f ( . 4f, . 4f ) } ;
var im1 = WindowsFormsApplication2 . Properties . Resources . LBB ;
Texture tx2 = CreateTexture1 ( im1 ) ;
Sprite sp2 = new Sprite ( tx2 ) { Scale = new Vector2f ( . 4f, . 4f ) , Position = new Vector2f ( 0 , 250 ) } ;
Texture tx3 = CreateTexture2 ( im1 ) ;
Sprite sp3 = new Sprite ( tx3 ) { Scale = new Vector2f ( . 4f, . 4f ) , Position = new Vector2f ( 250 , 250 ) } ;
while ( wind . IsOpen ( ) )
{
wind . DispatchEvents ( ) ;
wind . Clear ( SFML . Graphics . Color . White ) ;
wind . Draw ( sp1 ) ;
wind . Draw ( sp2 ) ;
wind . Draw ( sp3 ) ;
wind . Display ( ) ;
}
}
static Texture CreateTexture1 ( Bitmap Im )
{
byte [ ] array = new byte [ Im . Width * Im . Height * 4 ] ;
int i = 0 ;
for ( int y = 0 ; y < Im . Height ; y ++ )
{
for ( int x = 0 ; x < Im . Width ; x ++ )
{
var px = Im . GetPixel ( x, y ) ;
array [ i ] = px . R ;
array [ i + 1 ] = px . G ;
array [ i + 2 ] = px . B ;
array [ i + 3 ] = px . A ;
i += 4 ;
}
}
var tx = new Texture ( ( uint ) Im . Width , ( uint ) Im . Height ) ;
tx . Update ( array ) ;
return tx ;
}
static Texture CreateTexture2 ( Bitmap Im )
{
MemoryStream stm = new MemoryStream ( ) ;
Im . Save ( stm, System. Drawing . Imaging . ImageFormat . Png ) ;
return new Texture ( stm ) ;
}
}
}