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;
I face problem when we hit the line Image oImage = Image.FromStream((Stream)ms); this line is executed, but afterwards I get an exception "Parameter is not valid."
I'm guessing the imgData array doesn't actually contain a valid image (or one that Image.FromStream() understands at least).
Try checking the data against what you think it should be. You can also try saving the stream to a file and opening it that way - I'm guessing it will fail as "invalid format". If it opens correctly, have a look at this related question.
Related
I am trying to display a bitmap that is stored in a binary file.
The binary file is set up like so:
A Header structure that is 1024 bytes.
Pixels for the bitmap image (width * height * bytesperpixel - the header struct contains this info).
First I create a byte array:
var headerArray = new byte[Marshal.SizeOf(typeof(TestClass.BMPStruct))]; //size of the struct here is 1024
Then I create a FileStream on the file and read in the header first. I get bitmap's width + height + bytesperpixel from the header struct, and then read in the right amount of bytes after the header.
I then create a memory stream on those bytes and try creating a new bitmap.
using (FileStream fs = new FileStream(#"C:\mydrive\testFile.onc", FileMode.Open))
{
fs.Position = 0; //make sure the stream is at the beginning
fs.Read(headerArray, 0, 1024); //filestream position is 1024 after this
var headerStruct = StructsHelper.ByteArrayToStructure<TestClass.BMPStruct>(headerArray);
int bytesperpixel = headerStruct.BitsPerPixel / 8; //headerStruct.BitsPerPixel is 8 here
int pixelscount = headerStruct.BitmapWidth * headerStruct.BitmapHeight * bytesperpixel; //BitmapWidth = 296, BitmapHeight = 16, bytesperpixel = 1
var imageArray = new byte[pixelscount]; //pixelscount = 4736
try //now read in the bitmap's bytes
{
fs.Read(imageArray, 0, pixelscount); //filestream position is 5760 after this line
}
catch (Exception ex)
{
}
Bitmap bmp;
using (var ms = new MemoryStream(imageArray))
{
try
{
bmp = new Bitmap(ms); //error thrown here Exception thrown: 'System.ArgumentException' in System.Drawing.dll
//Parameter is not valid
}
catch (Exception ex)
{
}
}
}
On the line bmp = new Bitmap(ms), I get a System.ArgumentException in System.Drawing.dll. My try/catch shows a Parameter is not valid. exception.
I've seen a few other questions on this site with the same error, but none of the solutions have worked from the ones I've seen.
I have a running code, which gets any filetypes and show that file in a picturebox full of black and white pixels representing opened file bits
////////////////
int bmpWidth = 128000;
int startIndex = 0;
Int64 tempz = Convert.ToInt64(bmpWidth);
long tmp2 = fs.Length / tempz + 1;
int bmpHeight = Convert.ToInt32(tmp2);
Bitmap bmp = new Bitmap(bmpWidth, bmpHeight, PixelFormat.Format1bppIndexed);
////////////////
long all = 0;
byte[] array = new byte[bmpWidth];
int read = 0;
fs.Seek(startIndex, SeekOrigin.Begin);
all += startIndex;
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);
Int64 ptrFirstPixel = bmpData.Scan0.ToInt64();
int y = 0;
while ((read = fs.Read(array, 0, array.Length)) > 0)
{
if (read < array.Length)
{
byte[] arrayNew = new byte[read];
Array.Copy(array, arrayNew, read);
array = arrayNew;
}
Marshal.Copy(array, 0, new IntPtr(ptrFirstPixel + y * bmpData.Stride), array.Length/8);
y++;
all += read;
}
bmp.UnlockBits(bmpData);
imageBox.Image = bmp;
I have a 4GB ram, how its possible that I'm opening a 4.5GB file?
And also, when I try opening 2 or 4 GB file, only 200MB of memory is used, where are the rest of the data coming from?
During marshal.copy and filestream.seek the system use memory for byte by byte for hole filestream and bitmap or its coming from hard disk?
I have a logical and semantic misunderstanding in my mind, any help!?
I'm working with JPG image type and this line image = Image.FromStream(ms); is giving an error Parameter is not valid.
What is wrong with this code?
private void button3_Click(object sender, EventArgs e)
{
Image partial=null;
Rectangle bounds;
Guid id;
if (diff != null)
{
ImageConverter converter = new ImageConverter();
var data = (byte[])converter.ConvertTo(diff, typeof(byte[]));
UnpackScreenCaptureData(data, out partial, out bounds,out id);
Image imgfirst = (Image)firstImg;
UpdateScreen(ref imgfirst, partial, bounds);
}
}
public static void UnpackScreenCaptureData(byte[] data, out Image image, out Rectangle bounds, out Guid id)
{
// Unpack the data that is transferred over the wire.
// Create byte arrays to hold the unpacked parts.
const int numBytesInInt = sizeof(int);
int idLength = Guid.NewGuid().ToByteArray().Length;
int imgLength = data.Length - 4 * numBytesInInt - idLength;
byte[] topPosData = new byte[numBytesInInt];
byte[] botPosData = new byte[numBytesInInt];
byte[] leftPosData = new byte[numBytesInInt];
byte[] rightPosData = new byte[numBytesInInt];
byte[] imgData = new byte[imgLength];
byte[] idData = new byte[idLength];
// Fill the byte arrays.
Array.Copy(data, 0, topPosData, 0, numBytesInInt);
Array.Copy(data, numBytesInInt, botPosData, 0, numBytesInInt);
Array.Copy(data, 2 * numBytesInInt, leftPosData, 0, numBytesInInt);
Array.Copy(data, 3 * numBytesInInt, rightPosData, 0, numBytesInInt);
Array.Copy(data, 4 * numBytesInInt, imgData, 0, imgLength);
Array.Copy(data, 4 * numBytesInInt + imgLength, idData, 0, idLength);
// Create the bitmap from the byte array.
MemoryStream ms = new MemoryStream(imgData, 0, imgData.Length);
ms.Write(imgData, 0, imgData.Length);
image = Image.FromStream(ms);
....
}
I think you have to reset your MemoryStream to position 0.
You can accomplish this by calling the Seek() method on the memory stream:
MemoryStream ms = new MemoryStream(imgData, 0, imgData.Length);
ms.Write(imgData, 0, imgData.Length);
ms.Seek(0, SeekOrigin.Begin); // Set stream position to 0.
image = Image.FromStream(ms);
I've made these codes to send and receive an Image with a TCP socket but the receive code didn't work.
This is the send code:
public void SendImage()
{
int ScreenWidth = Screen.GetBounds(new Point(0, 0)).Width;
int ScreenHeight = Screen.GetBounds(new Point(0, 0)).Height;
Bitmap bmpScreenShot = new Bitmap(ScreenWidth, ScreenHeight);
Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
gfx.CopyFromScreen(0, 0, 0, 0, new Size(ScreenWidth, ScreenHeight));
bmpScreenShot.Save(Application.StartupPath + "/ScreenShot.jpg", ImageFormat.Jpeg);
byte[] image = new byte[1];
bmpScreenShot = ResizeBitmap(bmpScreenShot, 300, 300);
image = ImageToByte(bmpScreenShot);
//get the length of image (length of bytes)
int NumberOfBytes = image.Length;
//put the size into a byte array
byte[] numberofbytesArray = BitConverter.GetBytes(NumberOfBytes);
//send the size to the Client
int sizesend = sck.Send(numberofbytesArray, 0, numberofbytesArray.Length, 0);
if (sizesend > 0)
{
MessageBox.Show("Size Sent");
}
//send the image to the Client
int imagesend =sck.Send(image, 0, NumberOfBytes, 0);
if (imagesend > 0)
{
MessageBox.Show("Image Sent");
}
}
And here is the receive code:
public void ReceiveImage()
{
if (sck.Connected)
{
{
NetworkStream stream = new NetworkStream(sck);
byte[] data = new byte[4];
//Read The Size
stream.Read(data, 0, data.Length);
int size = (BitConverter.ToInt32(data,0));
// prepare buffer
data = new byte[size];
//Load Image
int read = 0;
while (read != data.Length)
{
read += stream.Read(data, read, data.Length - read);
}
//stream.Read(data, 0, data.Length);
//Convert Image Data To Image
MemoryStream imagestream = new MemoryStream(data);
Bitmap bmp = new Bitmap(imagestream);
pictureBox1.Image = bmp;
}
}
}
The problem is when i send the size, its sent as 5kb but when i receive it i find it 2GB and this error comes up:
Unable to read data from the transport connection. An operation on a socket could be performed because the system lacked sufficient buffer space or because a queue was full.
The error is at this statement read += stream.Read(data, read, data.Length - read);
I would try getting smaller chunks of data. In your code you're starting off with all the data (2GB at a time in the case that fails. Drop that down to something smaller--the data is sent in chunks anyway. For example:
read += stream.Read(buffer, read, 20480);
this will read about 2k at a time so as to not be larger than the buffer space or be too large for the queue.
If you've allocated a buffer of 2GB in size, your application likely has very little memory left. The underlying framework is probably unable to allocated 2GB of data for itself (4GB total allocated) to transfer data.
I made this code to receive an image and convert it to bitmap image but it doesn't work.
Here is the code:
public void ReceiveImage()
{
NetworkStream stream = new NetworkStream(socket);
byte[] data = new byte[4];
stream.read(data,0,data.length,0)
int size = BitConverter.ToInt32(data,0);
data = new byte[size];
stream.read(data,0,data.length)
MemoryStream imagestream = new MemoryStream(data);
Bitmap bmp = new Bitmap(imagestream);
picturebox1.Image = bmp;
}
It gets to:
Bitmap bmp = new Bitmap(imagestream);
And gives me this error:
Parameter is not valid
This is an alternative method
int w= 100;
int h = 200;
int ch = 3; //number of channels (ie. assuming 24 bit RGB in this case)
byte[] imageData = new byte[w*h*ch]; //you image data here
Bitmap bitmap = new Bitmap(w,h,PixelFormat.Format24bppRgb);
BitmapData bmData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
IntPtr pNative = bmData.Scan0;
Marshal.Copy(imageData,0,pNative,w*h*ch);
bitmap.UnlockBits(bmData);
You are probably not receiving enough bytes in stream.read(data,0,data.length) since Read does not ensure that it will read data.length bytes. you have to check its return value and continue to read till data.Length bytes are read.
See : Stream.Read Method's return value
int read = 0;
while (read != data.Length)
{
read += stream.Read(data, read, data.Length - read);
}
PS: I am assuming lengths and reads are typos.
I assume you have a table and want to receive the picture from database.
int cout = ds.Tables["TableName"].Rows.Count;
if (cout > 0)
{
if (ds.Tables["TableName"].Rows[cout - 1]["Image"] != DBNull.Value)
{
var data = (byte[])(ds.Tables["TableName"].Rows[cout - 1]["Image"]);
var stream = new MemoryStream(data);
pictureBox1.Image = Image.FromStream(stream);
}
else
{
pictureBox1.Image = null;
}
}
Try this:
int size = BitConverter.ToInt32(data.Reverse().ToArray(),0);