Image Retrieve using c# - c#

byte[] imageData = null;
long byteSize = 0;
byteSize = _reader.GetBytes(_reader.GetOrdinal(sFieldName), 0, null, 0, 0);
imageData = new byte[byteSize];
long bytesread = 0;
int curpos = 0, chunkSize = 500;
while (bytesread < byteSize)
{
// chunkSize is an arbitrary application defined value
bytesread += _reader.GetBytes(_reader.GetOrdinal(sFieldName), curpos, imageData, curpos, chunkSize);
curpos += chunkSize;
}
byte[] imgData = imageData;
MemoryStream ms = new MemoryStream(imgData);
Image oImage = Image.FromStream((Stream)ms);
return oImage;
Code creates problem when "Image oImage = Image.FromStream((Stream)ms);" line executes.....This line shows "Parameter is not valid" message .......Why it occurs? Help me. I want to retrieve image from database ....I work on C# window vs05 .....Can any one help me? byte[] contain value. All works well, just problem occurs when this line executes.

A simple if statement should solve your problem before creating the memory stream
if (imageData.Length != 0)
{
MemoryStream ms = new MemoryStream(imageData);
Image oImage = Image.FromStream((Stream)ms);
return oImage;
}
return null;

I can't really spot any errors in this code (other than the MemoryStream not being disposed, and that it's not necessary to cast it to Stream when passing it to the Image.FromStream method; but those should not cause your error). I would do the following in order to try to find the error:
Write the byte data to a file and try to open the image in a graphics program (to verify that the byte data does indeed represent a valid image). My guess is that this would fail.
Check the code that writes the data to the database (perhaps perform the same trick as in the previous point; write it to a file and try to open the file)

Related

C# Reading Bitmap from Stream

I've a network stream which sends a name and a picture. Name and picture start and end with a specific word
Example:
BeginNameXXXXXXXEndNameBeginPicYYYYYYYYYEndPic
I'll collect the stream in blocks and check if the last block contains the stop word of the picture.
byte[] data = new byte[2048];
int numBytesRead = stream.Read(data, 0, 2048);
if (numBytesRead > 0)
{
code += Encoding.ASCII.GetString(data, 0, numBytesRead);
}
If yes I'll stop collecting and divide the String into the name part and the picture part.
In principle I should have now a string only containing the picture.
Afterwards I try to save it as image but I only get an exception on the last code step
byte[] toEncodeAsBytes = ASCIIEncoding.ASCII.GetBytes(code);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
ms.Position = 0;
var image = Image.FromStream(ms, true);
Exception thrown: 'System.ArgumentException' in System.Drawing.dll
Any ideas what could be wrong?

Get Binary Data From Client and Save it as image

I created local server, that should get image files as binary data and save them back as images in hard drive.
Socket mySocket = myListener.AcceptSocket();
#region Connection Check
if (mySocket.Connected)
{
============
/* Some Code For Displaying Information*/
============
byte[] data = new byte[mySocket.ReceiveBufferSize];
int i = mySocket.Receive(data, data.Length, 0);
byteArrayToImage(data);
mySocket.Close();
}
byteArrayToImage method Converts byte Array to Image file and saves on hard drive, here's the code
public void byteArrayToImage(Byte[] data)
{
MemoryStream ms = new MemoryStream(data);
Image img = Image.FromStream(ms);
img.Save(#"C:\MyPersonalwebServer\ImageData\img.png", ImageFormat.Png);
}
but I get ArgumentException here: Image img = Image.FromStream(ms)
Here is part of data array: http://s43.radikal.ru/i101/1403/78/1913ab884790.png
Any ideas how to fix it?
Thanks in advance.
The following code works for me:
var buffer = new byte[256];
FileStream fs = new FileStream(#"D:\test.png", FileMode.Open);
var ms = new MemoryStream();
int readCtr;
while ((readCtr = fs.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, readCtr);
}
Image img = Image.FromStream(ms);
img.Save(#"D:\test2.png", ImageFormat.Png);
Are you sure that the data you are sending from the client connection is complete/clean?
Make sure the data you are sending from the client isn't appending null bytes when performing Socket.Send(), or try clean it up server-side by stripping any null bytes from the end of the byte array:
buffer = buffer.Where(x => x != (byte)0).ToArray();
You could also check the size of the image manually against the content received server-side using standard debug practices/console output.
Either way, I dont think your code would be failing if the byte array had valid content.

IP camera streaming error

I have a Samsung IP camera and I want to stream it in to my c# program, but when I run the program I got 'invalid parameter' error.
private void button1_Click(object sender, EventArgs e) { while (true) {
string sourceURL = url; byte[] buffer = new byte[100000];
int read, total = 0;
// create HTTP request
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sourceURL);
req.Credentials = new NetworkCredential("admin", "4321");
// get response
WebResponse resp = req.GetResponse();
// get response stream
Stream stream = resp.GetResponseStream();
// read data from stream
while ((read = stream.Read(buffer, total, 1000)) != 0)
{
total += read;
}
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));
pictureBox1.Image = bmp;
}
}
What might be the problem?
You are not building the correct buffer, you are overriding the old buffer with new buffer each time while there is new data, idea to fix it:
List<byte> fullData = new List<Byte>();
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)//also > 0 not == 0 because of it can be -1
{
fullData.AddRange(new List<Byte>(buffer).GetRange(0, read));//only add the actual data read
}
byte[] dataRead = fullData.ToArray();
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(dataRead , 0, dataRead.Lenght));
My guess (since you don't indicate the error) is that the image has gone over 100,000 bytes, which your code doesn't handle at all. I would, instead:
byte[] buffer = new byte[10 * 1024];
...
using(var ms = new MemoryStream())
{
// read everything in the stream into ms
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
// rewind and load the bitmap
ms.Position = 0;
Bitmap bmp = (Bitmap)Bitmap.FromStream(ms);
pictureBox1.Image = bmp;
}
kinda late answer relative to the time of the question; however, since I'm hunting down similar issues and this has apparently not been answered, I'm adding my two cents...
There are two issues here as I see it:
First:
You don't wanna put the event handler of a button-click into an endless loop. This should probably be a thread of some type so that the event handler can return.
Second:
As mentioned in another comment, your code is expecting the response to be a raw image of some type, and most likely it is not. Your camera may eventually send MJPG, but that doesn't mean it comes raw. Sometimes you have to send other commands to the camera and then when you actually start getting the MJPG stream you have to parse it and extract headers prior to sending the portion of the image to some picturebox. You're probably getting some kind of html response from the camera (as I am) and when you try to pass that data to a method that is expecting the data to be some image format (likely JPEG), then you get the invalid parameter error.
Can't say I know how to solve the problem cause it depends on the camera. If there is some kind of standard interface for these cameras I'd sure like to know what it is! Anyway, HTH...

Image.FromStream() method returns Invalid Argument exception

I am capturing images from a smart camera imager and receiving the byte array from the camera through socket programming (.NET application is the client, camera is the server).
The problem is that i get System.InvalidArgument exception at runtime.
private Image byteArrayToImage(byte[] byteArray)
{
if(byteArray != null)
{
MemoryStream ms = new MemoryStream(byteArray);
return Image.FromStream(ms, false, false);
/*last argument is supposed to turn Image data validation off*/
}
return null;
}
I have searched this problem in many forums and tried the suggestions given by many experts but nothing helped.
I dont think there is any problem with the byte array as such because When i feed the same byte array into my VC++ MFC client application, i get the image. But this doesn't somehow work in C#.NET.
Can anyone help me ?
P.S :
Other methods i've tried to accomplish the same task are:
1.
private Image byteArrayToImage(byte[] byteArray)
{
if(byteArray != null)
{
MemoryStream ms = new MemoryStream();
ms.Write(byteArray, 0, byteArray.Length);
ms.Position = 0;
return Image.FromStream(ms, false, false);
}
return null;
}
2.
private Image byteArrayToImage(byte[] byteArray)
{
if(byteArray != null)
{
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
Bitmap b = (Bitmap)tc.ConvertFrom(byteArray);
return b;
}
return null;
}
None of the above methods worked. Kindly help.
Image.FromStream() expects a stream that contains ONLY one image!
It resets the stream.Position to 0. I've you have a stream that contains multiple images or other stuff, you have to read your image data into a byte array and to initialize a MemoryStream with that:
Image.FromStream(new MemoryStream(myImageByteArray));
The MemoryStream has to remain open as long as the image is in use.
I've learned that the hard way, too.
Maybe the image is embedded in an OLE field and you have to consider the 88 bytes OLE header plus payload:
byteBlobData = (Byte[]) reader.GetValue(0);
stream = new MemoryStream(byteBlobData, 88, byteBlobData.Length - 88);
img = Image.FromStream(stream);
I'm guessing that something is going wrong when receiving the file from the server. Perhaps you're only getting part of the file before trying to convert it to an Image? Are you sure it's the exact same byte array you're feeding the C++ application?
Try saving the stream to a file and see what you get. You might be able to uncover some clues there.
You can also add a breakpoint and manually compare some of the bytes in the byte array to what they're supposed to be (if you know that).
Edit: It looks like there's nothing wrong with receiving the data. The problem is that it's in raw format (not a format that Image.FromStream understands). The Bitmap(Int32, Int32, Int32, PixelFormat, IntPtr) constructor may be of use here. Or, you can create the blank bitmap and blt it manually from the raw data.
I've had this problem when doing this:
MemoryStream stream = new MemoryStream();
screenshot.Save(stream, ImageFormat.Png);
byte[] bytes = new byte[stream.Length];
stream.Save(bytes, 0, steam.Length);
With the last 2 lines being the problem. I fixed it by doing this:
MemoryStream stream = new MemoryStream();
screenshot.Save(stream, ImageFormat.Png);
byte[] bytes = stream.ToArray();
And then this worked:
MemoryStream stream = new MemoryStream(bytes);
var newImage = System.Drawing.Image.FromStream(stream);
stream.Dispose();
System.InvalidArgument means The stream does not have a valid image format, i.e. an image type that is not supported.
Try this:
public Image byteArrayToImage(byte[] item)
{
Image img=Image.FromStream(new MemoryStream(item));
img.Save(Response.OutputStream, ImageFormat.Gif);
return img;
}
Hope it helps!
I've had the same problem in the past and it was caused by a leak within the windows GDI libraries, which is what 'Bitmap' uses. If this happening all the time for you then its probably unrelated, however.
this code is working
string query="SELECT * from gym_member where Registration_No ='" + textBox9.Text + "'";
command = new SqlCommand(query,con);
ad = new SqlDataAdapter(command);
DataTable dt = new DataTable();
ad.Fill(dt);
textBox1.Text = dt.Rows[0][1].ToString();
textBox2.Text = dt.Rows[0][2].ToString();
byte[] img = (byte[])dt.Rows[0][18];
MemoryStream ms = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(ms);
ms.Dispose();
Try to use something similar to what is described here https://social.msdn.microsoft.com/Forums/vstudio/en-US/de9ee1c9-16d3-4422-a99f-e863041e4c1d/reading-raw-rgba-data-into-a-bitmap
Image ImageFromRawBgraArray(
byte[] arr,
int charWidth, int charHeight,
int widthInChars,
PixelFormat pixelFormat)
{
var output = new Bitmap(width, height, pixelFormat);
var rect = new Rectangle(0, 0, width, height);
var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat);
// Row-by-row copy
var arrRowLength = width * Image.GetPixelFormatSize(output.PixelFormat) / 8;
var ptr = bmpData.Scan0;
for (var i = 0; i < height; i++)
{
Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength);
ptr += bmpData.Stride;
}
output.UnlockBits(bmpData);
return output;
}
After load from DataBase byteArray has more byte than one image. In my case it was 82.
MemoryStream ms = new MemoryStream();
ms.Write(byteArray, 82, byteArray.Length - 82);
Image image = Image.FromStream(ms);
And for save in the DB I insert 82 byte to begin stream. Properties.Resources.ImgForDB - it is binary file that contain those 82 byte. (I get it next path - Load Image from DB to MemoryStream and save to binary file first 82 byte. You can take it here - https://yadi.sk/d/bFVQk_tdEXUd-A)
MemoryStream temp = new MemoryStream();
MemoryStream ms = new MemoryStream();
OleDbCommand cmd;
if (path != "")
{
Image.FromFile(path).Save(temp, System.Drawing.Imaging.ImageFormat.Bmp);
ms.Write(Properties.Resources.ImgForDB, 0, Properties.Resources.ImgForDB.Length);
ms.Write(temp.ToArray(), 0, temp.ToArray().Length);
cmd = new OleDbCommand("insert into Someone (first, Second, Third) values (#a,#b,#c)", connP);
cmd.Parameters.AddWithValue("#a", fio);
cmd.Parameters.AddWithValue("#b", post);
cmd.Parameters.AddWithValue("#c", ms.ToArray());
cmd.ExecuteNonQuery();

ArgumentException when converting byte[] to Bitmap c#

I'm trying to convert a byte array to a bitmap but it always shows me:
System.ArgumentException: Parameter is not valid.
My code is as follows:
I'm passing the bytes through a webservice with:
string DecodedString = string.Empty;
DecodedString = System.Text.Encoding.GetEncoding(1251).GetString(bytes);
sResult = sResult + "<Photo>" +XmlConvert.EncodeName(DecodedString) + "</Photo>";
and in my webPage:
byte[] bytes = (Byte[])System.Text.Encoding.GetEncoding(1251).GetBytes(XmlConvert.DecodeName(xDocument.SelectSingleNode("Response/Images/Photo").InnerText));
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
System.Drawing.Bitmap b = new System.Drawing.Bitmap(ms);//(System.Drawing.Image.FromStream(ms));
Try passing the string as a Base64:
string DecodedString = string.Empty;
DecodedString = System.Convert.ToBase64String(bytes)
sResult = sResult + "<Photo>" +XmlConvert.EncodeName(DecodedString) + "</Photo>";
...
byte[] bytes = System.Convert.FromBase64String(xDocument.SelectSingleNode("Response/Images/Photo").InnerText);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
System.Drawing.Bitmap b = System.Drawing.Image.FromStream(ms);
You also won't need to use XmlConvert to encode/decode the string.
I did it, with the help of all of you, here is my page code
byte[] bytes = System.Convert.FromBase64String(xDocument.SelectSingleNode("Response/Images/Photo").InnerText);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
System.Drawing.Bitmap b = new System.Drawing.Bitmap(ms); //(Bitmap)System.Drawing.Image.FromStream(ms);
System.Drawing.Imaging.FrameDimension frameDim;
frameDim = new System.Drawing.Imaging.FrameDimension(b.FrameDimensionsList[0]);
int NumberOfFrames = b.GetFrameCount(frameDim);
string[] paths = new string[NumberOfFrames];
for (int i = 0; i < NumberOfFrames; i++)
{
b.SelectActiveFrame(frameDim, i);
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(b);
paths[i] = imagePathfile.Remove(imagePathfile.Length - 4, 4) + i.ToString() + ".gif";
bmp.Save(paths[i], System.Drawing.Imaging.ImageFormat.Gif);
//bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
bmp.Dispose();
}
Image1.Src = paths[0];
//Check if there's more than 1 image cause its a TIFF
if (paths.Length>1)
{
Image2.Src = paths[1];
}
I had a similar problem recently, but using Silverlight. I ended up needing to create a Custom HTTP Handler in order to pass the byte[] that defined the image back as a stream.
See http://www.dotnetcurry.com/ShowArticle.aspx?ID=220
Edit: This allows you to avoid worrying about XML encoding, and passes the image back in Binary form... YMMV
According to MSDN:
ArgumentException - The stream does not have a valid image format
I believe your problem is in the original byte[] array you are passing to the web service.
According to one of your comments, you did:
System.IO.FileStream fs = new System.IO.FileStream(sPath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
int streamLength = Convert.ToInt32(fs.Length);
bytes = new byte[streamLength];
fs.Read(bytes, 0, streamLength);
fs.Read returns the number of bytes that have been read into the byte array; it doesn't always read the entire file!
Try using the StreamFile method from http://www.dotnetspider.com/resources/4515-convert-file-into-byte-array.aspx. (First result of Google search)
Try this:
byte[] bytes = System.Convert.FromBase64String(xDocument.SelectSingleNode("Response/Images/Photo").InnerText);
System.Drawing.ImageConverter imageConverter = new System.Drawing.ImageConverter();
Image image = imageConverter.ConvertFrom(bytes) as Image;
System.Drawing.Bitmap b = new System.Drawing.BitMap(image);
EDIT
Take a look at this:
Transfer any files on Web services by c#
actually i had been meet this problem, In my case, when i use IE browser, it is ok but when use another browser it always have the same error.
"Parameter is not valid exception is always happening in the same line of code:
System.Drawing.Image.FromStream(ms));"
So i think it seems this issue depend on browser and type of image (JPEG,JPEG2000).
Here is some code I used converting bytes to an image for a unit test:
protected override Image LoadImage()
{
//get a temp image from bytes, instead of loading from disk
//data:image/gif;base64,
byte[] bytes = Convert.FromBase64String("R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==");
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
}
To my understanding, the image can not be shown because the format of the image's bytes is not correct. Every image format has its own head or something.

Categories

Resources