WindowsForm - Load picturebox.image from a xml - c#

I'm having trouble loading an image "string" in the PictureBox control.
I am not able to find a way to charge it and do not know if it is possible to do it that way.
I tried the following code, but without success:
1st
var s= "0x89504E470D0A1A0A0000000D49484452000000900000005B0802000000130B9B9
8000000017352474200AECE1CE90000000467414D410000B18F0BFC6105000000097048597300000EC300000EC301C76FA8640000013B49444154785EEDD6410D00211443418470C4BF333C808977F8C9242B8094CE9675F7F10D4A600D3AABA3FE045CD8B01F8C0B736146B14C8030C2CA7E7977104618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB863DFFBF32F5C2C8C5B40000000049454E44AE426082";
picture.Image = Base64ToImage(s);
static Image Base64ToImage(string base64String)
{
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes);
return Image.FromStream(ms, true);
}
Can anyone help!?

This seems to be a red rectangle 91*144 if decoded properly.
remove 0x and space from string.
convert string to byte[] - I used converter found on StackOverFlow the one by CainKellye (How can I convert a hex string to a byte array?)
string s = "89504E470D0A1A0A0000000D49484452000000900000005B0802000000130B9B98000000017352474200AECE1CE90000000467414D410000B18F0BFC6105000000097048597300000EC300000EC301C76FA8640000013B49444154785EEDD6410D00211443418470C4BF333C808977F8C9242B8094CE9675F7F10D4A600D3AABA3FE045CD8B01F8C0B736146B14C8030C2CA7E7977104618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB86114618616502841156F6CB863DFFBF32F5C2C8C5B40000000049454E44AE426082";
byte[] imageBytes = StringToByteArrayFastest(s);
MemoryStream ms = new MemoryStream(imageBytes);
Bitmap bmp = (Bitmap)Image.FromStream(ms);
pictureBox1.Image = bmp;
and the result is:

I don't think s is a base 64 string, it looks more like hexadecimal - it even still has 0x in front of it and the 'digits' are no higher than F. You should definitely remove the 0x in front. To get a base 64 string, you could use the code from this website (I haven't tested it):
public static string ConvertHexStringToBase64(string hexString)
{
if (hexString.Length % 2 > 0)
throw new FormatException("Input string was not in a correct format.");
if (Regex.Match(hexString, "[^a-fA-F0-9]").Success == true)
throw new FormatException("Input string was not in a correct format.");
byte[] buffer = new byte[hexString.Length / 2];
int i=0;
while (i < hexString.Length) {
buffer[i / 2] = byte.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
i += 2;
}
return Convert.ToBase64String(buffer);
}

Related

Converting byte[] to Image C# (ArgumentException Error)

(I use Google Translate, sorry..)
I'm trying to do a small project with shorthand.
I found similar topics, but they are not what I need.
The bottom line is, I get an image at the input, convert it to byte [], then to binary. (Everything is OK here)
Then I translate the text to binary. (Everything is OK here)
in the binary array, I change the last two bits to the ones I need.
I translate everything back to byte[] (everything is OK Here)
and then I try to convert byte[] to Image and an error occurs (Incorrect argument)
If I do not make changes to binary, the conversion is successful ( and I get the same image that I gave at the input).
change code in the binary array:
public byte[] ShifrMessage(byte[] input, string message)
{
byte[] ConvertToByteArray(string str, Encoding encoding)
{
return encoding.GetBytes(str);
}
String ToBinary(Byte[] data)
{
return string.Join("", data.Select(byt => Convert.ToString(byt, 2).PadLeft(8, '0')));
}
//message in the binary
var binaryString = ToBinary(ConvertToByteArray(message, Encoding.ASCII));
byte[] ret = new byte[input.Length];
for (int i = 0; i < ret.Length; i++)
{
string a = Convert.ToString(ret[i], 2).PadLeft(8, '0');
//changing the last two bits
if (binaryString.Length >= 2)
{
a = a.Substring(0, a.Length - 2) + binaryString.Substring(0, 2);
binaryString = binaryString.Substring(2);
}
///
byte b = StringToByte(a);
ret[i] = b;
}
return ret;
}
I assume that when converting to Image, the integrity of the image that was changed is checked.
conversion:
public Image byteArrayToImage(byte[] byteArrayIn)
{
using (var ms1 = new MemoryStream(byteArrayIn))
{
return Image.FromStream(ms1);
}
}
Can you tell me what the problem might be?

String with varbinary to ImageView

I'm trying to send a string contained a varbinary into an ImageView
string ImageHexAsString = "0xFFD8FFE000104A464946000101010...";//Here is my string as VarBinary
byte[] toBytes = Encoding.ASCII.GetBytes(ImageHexAsString); //Here i'm converting string to byte[]
Bitmap bitmap = BitmapFactory.DecodeByteArray(toBytes, 0, toBytes.Length);
imageView.SetImageBitmap(bitmap); //and here i'm send it to imageview
I get an empty white image nothing more.Is something wrong?
UPDATE: Just realized this is about c#, not Java. Answer is the same though. Possible duplicate of How do you convert a byte array to a hexadecimal string, and vice versa?
This is probably a duplicate of Convert a string representation of a hex dump to a byte array using Java?.
What's happening is that you shouldn't try and interpret the hex string as text (with Encoding.ASCII.GetBytes()), because it isn't, it's an image.
SOLVED:
ImageHexAsString = "0xFFD8FFE000104A4649460001010100....";
List<byte> byteList = new List<byte>();
string hexPart = ImageHexAsString.Substring(2);
for (int i = 0; i < hexPart.Length / 2; i++)
{
string hexNumber = hexPart.Substring(i * 2, 2);
byteList.Add((byte)Convert.ToInt32(hexNumber, 16));
}
byte[] original = byteList.ToArray();
Bitmap bitmap = BitmapFactory.DecodeByteArray(original, 0, original.Length);
imageView.SetImageBitmap(bitmap);
it seems to work with 256x256 resolution I dont know how to change the struck if image is bigger

"Parameter not valid" error when trying to save the image converted from byte

currently I am testing a script that tries to save an image file converted from a string of HEX, however, when I try to execute the Save command, parameter not valid appears.
// Some junk hex image data
string hexImgData = #"FFD8FFE000104A46494600010200006400640000FFFFD9";
// Call function to Convert the hex data to byte array
byte[] newByte = ToByteArray(hexImgData);
MemoryStream memStream = new MemoryStream(newByte);
// Save the memorystream to file
Bitmap.FromStream(memStream).Save("C:\\img.jpg");
// Function converts hex data into byte array
public static byte[] ToByteArray(String HexString)
{
int NumberChars = HexString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(HexString.Substring(i, 2), 16);
}
return bytes;
}
Currently I am still in the process of looking what causes this, please advice.
As was mentioned in the comments, your bitmap format is wrong, all you have is some random hex data and the Bitmap.FromStream method has no idea what to do with it. If you look at this link which discusses how to create a bitmap file with a hex editor it discusses the BitmapHeader, BitmapInfoHeader, and the Pixel RGB Data. I was able to create a bitmap using your code by taking the data from their example and using it.
string bitmapHeader = "424D860000000000000036000000";
string bitmapInfoHeader = "280000000500000005000000010018000000000050000000C40E0000C40E00000000000000000000";
string pixelData = "0000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF00";
string hexImgData = bitmapHeader + bitmapInfoHeader + pixelData;
// Call function to Convert the hex data to byte array
byte[] newByte = ToByteArray(hexImgData);
MemoryStream memStream = new MemoryStream(newByte);
pictureBox1.Image = Bitmap.FromStream(memStream);
It seems you need convert incoming string from Base64 to byte array like this:
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);

byte array created in ActionScript to be used in C#

I have an application that asks users to upload a photo via flash. Flash then turns this photo into a byte array. Here is that code:
var rect:Rectangle=new Rectangle(0,0,imageWidth,imageHeight);
// create BitmapData
var bmd:BitmapData=new BitmapData(imageWidth,imageHeight,true,0);
bmd.draw(myMovieClip);// get the image out of the MovieClip
// create byte array
var binaryData:ByteArray = new ByteArray();
binaryData.position=0;// start at the beginning
binaryData.writeBytes(bmd.getPixels(rect));
After the byte array is created, it is base64 encoded and posted to an IIS server that houses an .ashx handler. In the handlers ProcessRequest method the following code is used to write the data out to a file:
try
{
// Convert from base64string to binary array and save
byte[] contents = Convert.FromBase64String(encodedData); //encodedData is the Base64 encoded byte array from flash
File.WriteAllBytes(fullPath, (byte[])contents);
context.Response.Write("result=1");
}
catch (Exception ex)
{
context.Response.Write("errMsg=" + ex.Message + "&result=0");
}
So far so good. No problems up to this point.
The problem occurs after retrieving the byte data that is stored in the file and attempting to recreate the image on the server side in C#.
When I try the following:
try
{
var fileBytes = File.ReadAllBytes(path);
Bitmap bmp;
using (var ms = new MemoryStream(fileBytes))
{
ms.Position = 0;
using (var i = Image.FromStream(ms, false, true))
{
bmp = new Bitmap(i);
}
}
}
catch (Exception ex)
{
//error: ex.Message is always “the parameter is not valid”
}
The program always throws on this line with the message “the parameter is not valid”
using (var i = Image.FromStream(ms, false, true))
Any advice is greatly appreciated.
BitmapData.getPixels() is just a ByteArray of 32 bit uint values (ARGB) for each pixel, are you sure C# Image.FromStream can handle such format correct? As an alternative you can encode your image to PNG or JPG bytes (there are several PNG/JPG encoders, flex version or as3corelib)
Its turns out that fsbmain is correct above. Image.FromStream does not have the ability to take the data from BitmapData.getPixels() and create an image from it.
In order to get back to the original image, I needed to use Bitmap.SetPixel() and loop thru the byte array setting the ARGB values as shown below:
(please note that the height and width are prepended to the byte array. Thats why I'm using Buffer.BlockCopy to split the array up into the parts that I need)
static void Main(string[] args)
{
string path = #"C:\data\TUIxMTA0ODM5\imagea.b64";
string imagepath = #"C:\data\newPic.jpg";
try
{
//get the data from the file
var f = File.ReadAllBytes(path);
//get the height and width of the image
var newArr = new byte[4];
Buffer.BlockCopy(f, 0, newArr, 0, 4);
var height = ReadShort(newArr, 0);
var width = ReadShort(newArr, 2);
//get the pixel data
var myArr = new byte[f.Length - 4];
Buffer.BlockCopy(f, 4, myArr, 0, f.Length - 4);
//create the new image
var bmp = new Bitmap(width, height);
int counter = 0;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
bmp.SetPixel(x, y, Color.FromArgb(myArr[counter], myArr[++counter], myArr[++counter], myArr[++counter]));
counter++;
}
}
bmp.Save(imagepath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static short ReadShort(byte[] buffer, int offset)
{
return (short)((buffer[offset + 0] << 8) + buffer[offset + 1]);
}
I hope this helps.

zlib from C++ to C#(How to convert byte[] to stream and stream to byte[])

My task is to decompress a packet(received) using zlib and then use an algoritm to make a picture from the data
The good news is that I have the code in C++,but the task is to do it in C#
C++
//Read the first values of the packet received
DWORD image[200 * 64] = {0}; //used for algoritm(width always = 200 and height always == 64)
int imgIndex = 0; //used for algoritm
unsigned char rawbytes_[131072] = {0}; //read below
unsigned char * rawbytes = rawbytes_; //destrination parameter for decompression(ptr)
compressed = r.Read<WORD>(); //the length of the compressed bytes(picture)
uncompressed = r.Read<WORD>(); //the length that should be after decompression
width = r.Read<WORD>(); //the width of the picture
height = r.Read<WORD>(); //the height of the picture
LPBYTE ptr = r.GetCurrentStream(); //the bytes(file that must be decompressed)
outLen = uncompressed; //copy the len into another variable
//Decompress
if(uncompress((Bytef*)rawbytes, &outLen, ptr, compressed) != Z_OK)
{
printf("Could not uncompress the image code.\n");
Disconnect();
return;
}
//Algoritm to make up the picture
// Loop through the data
for(int c = 0; c < (int)height; ++c)
{
for(int r = 0; r < (int)width; ++r)
{
imgIndex = (height - 1 - c) * width + r;
image[imgIndex] = 0xFF000000;
if(-((1 << (0xFF & (r & 0x80000007))) & rawbytes[((c * width + r) >> 3)]))
image[imgIndex] = 0xFFFFFFFF;
}
}
I'm trying to do this with zlib.NET ,but all demos have that code to decompress(C#)
private void decompressFile(string inFile, string outFile)
{
System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
try
{
CopyStream(inFileStream, outZStream);
}
finally
{
outZStream.Close();
outFileStream.Close();
inFileStream.Close();
}
}
public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}
My problem:I don't want to save the file after decompression,because I have to use the algoritm shown in the C++ code.
How to convert the byte[] array into a stream similiar to the one in the C# zlib code to decompress the data and then how to convert the stream back into byte array?
Also,How to change the zlib.NET code to NOT save files?
Just use MemoryStreams instead of FileStreams:
// Assuming inputData is a byte[]
MemoryStream input = new MemoryStream(inputData);
MemoryStream output = new MemoryStream();
Then you can use output.ToArray() afterwards to get a byte array out.
Note that it's generally better to use using statements instead of a single try/finally block - as otherwise if the first call to Close fails, the rest won't be made. You can nest them like this:
using (MemoryStream output = new MemoryStream())
using (Stream outZStream = new zlib.ZOutputStream(output))
using (Stream input = new MemoryStream(bytes))
{
CopyStream(inFileStream, outZStream);
return output.ToArray();
}
I just ran into this same issue.
For Completeness... (since this stumped me for several hours)
In the case of ZLib.Net you also have to call finish(), which usually happens during Close(), before you call return output.ToArray()
Otherwise you will get an empty/incomplete byte array from your memory stream, because the ZStream hasn't actually written all of the data yet:
public static void CompressData(byte[] inData, out byte[] outData)
{
using (MemoryStream outMemoryStream = new MemoryStream())
using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_DEFAULT_COMPRESSION))
using (Stream inMemoryStream = new MemoryStream(inData))
{
CopyStream(inMemoryStream, outZStream);
outZStream.finish();
outData = outMemoryStream.ToArray();
}
}
public static void DecompressData(byte[] inData, out byte[] outData)
{
using (MemoryStream outMemoryStream = new MemoryStream())
using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream))
using (Stream inMemoryStream = new MemoryStream(inData))
{
CopyStream(inMemoryStream, outZStream);
outZStream.finish();
outData = outMemoryStream.ToArray();
}
}
In this example I'm also using the zlib namespace:
using zlib;
Originally found in this thread:
ZLib decompression
I don't have enough points to vote up yet, so...
Thanks to Tim Greaves for the tip regarding finish before ToArray
And Jon Skeet for the tip regarding nesting the using statements for streams (which I like much better than try/finally)

Categories

Resources