none
Bitmap Image from Hex string - extra bytes being added RRS feed

  • Question

  • I have a Hex string that's coming from postscript file.  
    (This Hex string is for image - I need to modify RGB color values for this image and write it back to postscript file)  

    Below are the methods that I am using. I have commented out the method for updating color.


        public static void ProcessImageColourMapping()
        {
            string imageDataSource = "803fe0503824160d0784426150b864361d0f8844625138a4562d178c466351b8e4763d1f904864523924964d27944a6552b964b65d2f984c665339a4d66d379c4e6753b9e4f67d3fa05068543a25168d47a4526954ba648202";
            string imageDataSourceUpdated = GetUpdatedImage(imageDataSource);
        }
    
        public static string GetUpdatedImage(string strImageDataSource)
        {
            string imageDataSourceUpdated = "";
    
            byte[] imageBytes = StringToByteArray(strImageDataSource);
            Bitmap bitmapImage = ByteArrayToBitmap(imageBytes);
            //UpdateColour(bitmapImage);
            byte[] imageBytesUpdated = BitmapToByteArray(bitmapImage);
            imageDataSourceUpdated = ByteArrayToString(imageBytesUpdated);
    
            return imageDataSourceUpdated;
        }
    
        public static byte[] StringToByteArray(String imageHexString)
        {
            int numberOfChars = imageHexString.Length / 2;
            byte[] byteArray = new byte[numberOfChars];
            using (var sr = new StringReader(imageHexString))
            {
                for (int i = 0; i < numberOfChars; i++)
                    byteArray[i] = Convert.ToByte(new string(new char[2] { (char)sr.Read(), (char)sr.Read() }), 16);
            }
            return byteArray;
        }
    
        public static Bitmap ByteArrayToBitmap(byte[] byteArray)
        {
            int width = 986; //width and height are taken from postscript file for testing a single hex string.
            int height = 1;
            Bitmap bitmapImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
            BitmapData bmpData = bitmapImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);            
            try
            {                
                Marshal.Copy(byteArray, 0, bmpData.Scan0, byteArray.Length);
            }
            finally
            {
                bitmapImage.UnlockBits(bmpData);                
            }
            return bitmapImage;
        }
    
        public static byte[] BitmapToByteArray(Bitmap bitmap)
        {
            BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
            int numbytes = bmpdata.Stride * bitmap.Height;
            byte[] bytedata = new byte[numbytes];
            try
            {
                Marshal.Copy(bmpdata.Scan0, bytedata, 0, numbytes);            
            }
            finally
            {
                bitmap.UnlockBits(bmpdata);
            }
            return bytedata;
        }
    
        public static string ByteArrayToString(byte[] byteArray)
        {
            StringBuilder hex = new StringBuilder(byteArray.Length * 2);
            foreach (byte b in byteArray)
            {
                hex.AppendFormat("{0:x2}", b);
            }
            return hex.ToString();
        }

    **Issue:**  
    In below code, I am not updating anything for incoming Hex string `imageDataSource`.  
    Converting it to byte[] - then to Bitmap - Back to byte[] - and finally back to Hex string.

    So, `imageDataSourceUpdated` should have same value as `imageDataSource`.   
    However, when I finally check the value for `imageDataSourceUpdated`, it comes out as:  

    `803fe0503824160d0784426150b864361d0f8844625138a4562d178c466351b8e4763d1f904864523924964d27944a6552b964b65d2f984c665339a4d66d379c4e6753b9e4f67d3fa05068543a25168d47a4526954ba64820200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000`.....  
    So many zeros being appended.

    Can please guide what I am missing here.
    Monday, February 3, 2014 4:07 PM

Answers

  • Hi, the problem is from

    public static Bitmap ByteArrayToBitmap(byte[] byteArray)
    {
        int width = 986;
        ...
    }

    if pixel format is PixelFormat.Format32bppPArgb, it means there are 4 bytes for one pixel, if image width is 986 and height is 1, it means there should be 986 * 4 bytes in byteArray. so when run below code, byte array length of bmpData will be 986 * 4

    Bitmap bitmapImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
    BitmapData bmpData = bitmapImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);            
            

    and, the length of byteArray is 89, so, when copy byteArray to bmpData, only the first 89 bytes of bmpData are changed, the rest bytes in bmpData will be zero.

    Marshal.Copy(byteArray, 0, bmpData.Scan0, byteArray.Length);
    that is why you see a lot of zeros.

    Monday, February 3, 2014 5:42 PM