Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Issues Converting Resource File Images into Byte Arrays than into SFML Images  (Read 6714 times)

0 Members and 1 Guest are viewing this topic.

StormWingDelta

  • Sr. Member
  • ****
  • Posts: 365
    • View Profile
Not sure if it is the code I'm using or SFML but whatever the case something has imploded.  Managed to get it to a point that the only issue left is color not wanting to play nice and stay the same.  Worst case though is the image doesn't show or is turned into a line.  :( ???


Here's the current coding from the SFML images up above.
Image image = new Image((uint)TestImages.TestShip.Width,
                    (uint)TestImages.TestShip.Height,
                    GetRGBValues(new System.Drawing.Bitmap(TestImages.TestShip)));
                Image image2 = new Image((uint)TestImages.ClosedGridHall.Width,
                    (uint)TestImages.ClosedGridHall.Height,
                    GetRGBValues(new System.Drawing.Bitmap(TestImages.ClosedGridHall)));
                Image image3 = new Image((uint)TestImages.TestShip.Width,
                    (uint)TestImages.TestShip.Height,
                    MarshalImageToByteArray(new System.Drawing.Bitmap(TestImages.TestShip)));

                Sprite exsprite = new Sprite(new Texture(image));
                Sprite exsprite2 = new Sprite(new Texture(image2));
                Sprite exsprite3 = new Sprite(new Texture(image3));
 
Commented out the one that doesn't work for what I'm doing.  Now I'm down to 3 the commented out one doesn't work with images stored as resource files.
//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 an image of the several errors. >.>

Top two are fine but the image color is off.  The last one on the left is distorted to heck and back.  The one on the right is loaded from file normally.  I Have no idea where I'm messing up.  :(
I have many ideas but need the help of others to find way to make use of them.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
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);
        }
    }
}
 

Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

StormWingDelta

  • Sr. Member
  • ****
  • Posts: 365
    • View Profile
hmm should be interesting.  Also working on a version of my own to see if I can get it working myself too. :)  I'll post my solution if it works along with yours so people won't be asking about how to do this in the future. :)  Or at least so we can show them how to do it without having to get a headache. :D
I have many ideas but need the help of others to find way to make use of them.

StormWingDelta

  • Sr. Member
  • ****
  • Posts: 365
    • View Profile
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));
        }
 
I have many ideas but need the help of others to find way to make use of them.