Unhandled System.ArgumentException.. Additional Information: Parameter is not valid - c#

I have this code in c# that pulls images from database and shows them in PictureBox. Whenever I run code first, I get this error saying "An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll Additional information: Parameter is not valid." But if I terminate and rerun the program, it works just fine giving intended results. Here is part of the code that is giving me trouble:
private void buttonGetImage_Click(object sender, EventArgs e)
{
string baseUrl = "http://someurl";
HttpWebRequest request = null;
foreach (var fileName in fileNames)
{
string url = string.Format(baseUrl, fileName);
MessageBoxButtons buttons = MessageBoxButtons.OKCancel;
DialogResult result;
result = MessageBox.Show(url, fileName, buttons);
if (result == System.Windows.Forms.DialogResult.Cancel)
{
this.Close();
}
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = container;
response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
byte[] buffer = new byte[10000000];
int read, total = 0;
while ((read = stream.Read(buffer, total, 1000)) != 0)
{
total += read;
}
MemoryStream ms = new MemoryStream(buffer, 0, total);
ms.Seek(0, SeekOrigin.Current);
Bitmap bmp = (Bitmap)Bitmap.FromStream(ms);
pictureBoxTabTwo.Image = bmp;
this.pictureBoxTabTwo.SizeMode = PictureBoxSizeMode.Zoom;
pictureBoxTabTwo.Image.Save("FormTwo.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
Can someone help me to figure out what can be done?
Error is showing me line --> Bitmap bmp = (Bitmap)Bitmap.FromStream(ms);

Instead of using Bitmap class I used Image class in my program. What I was doing here was taking a stream and putting it into a byte array. And again converting content of that array back to stream. Instead, I used
Image img = Image.FromStream(stream)
In this case You don't even have to use MemoryStream. It is working perfectly find for me now.

Hard to tell from your code what the problem could be, but likely the query you are making on the server returns an unexpected response in some circumstances. You'd be best to get a snapshot of the returned stream when things goes wrong. It will allow you to diagnose the problem and take appropriate measures.

You need to do proper object disposal. Otherwise, the underlying connection doesn't close until the garbage collector catches up with the object and that can cause problems. Also, in .NET 4.0 and higher you can use the CopyTo method on Streams.
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = container;
using (response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
{
// All of this code is unnecessary if using .NET 4.0 or higher.
/*
byte[] buffer = new byte[10000000];
int read, total = 0;
while ((read = stream.Read(buffer, total, 1000)) != 0)
{
total += read;
}
MemoryStream ms = new MemoryStream(buffer, 0, total);
ms.Seek(0, SeekOrigin.Current);
*/
// Instead use the following
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
Bitmap bmp = (Bitmap)Bitmap.FromStream(ms);
pictureBoxTabTwo.Image = bmp;
this.pictureBoxTabTwo.SizeMode = PictureBoxSizeMode.Zoom;
pictureBoxTabTwo.Image.Save("FormTwo.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}

You can try it
pictureBox1.Image = new Bitmap(sourceBitmap);

Related

error resolving System.ArgumentException using wcf service

I want to convert Image to Base64String format,For that I am using this code
string conversionData = imageToBase64("http//localhost/MyService/Images/myImage.png");
the code of "imageToBase64()" is
private string imageToBase64(string path)
{
using(Image image = Image.FromFile(path))
{
using(MemoryStream m = new MemoryStream())
{
byte[] imageBytes = m.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
}
When I am passing path to this method I am getting the error "An exception of type 'System.ArgumentException' occered ...".
thanks in advance
take a look :https://stackoverflow.com/questions/21325661/convert-image-path-to-base64-string.You missed image.Save(m, image.RawFormat)
Hope it will help
The parameter of fromfile cannot be URI, otherwise an error will be reported.
The interface that accesses WCF will return stream. We need to use the Httpwebrequest request interface to receive its stream,then save it locally before using fromfile.Here is a Demo:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:8000/Service/GetImage?width=50&height=40");
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (File.Exists("d:\\name.png"))
File.Delete("d:\\name.png");
Stream outStream = System.IO.File.Create("d:\\name.png");
Stream inStream = response.GetResponseStream();
int l;
byte[] buffer = new byte[1024];
do
{
l = inStream.Read(buffer, 0, buffer.Length);
if (l > 0)
outStream.Write(buffer, 0, l);
}
while (l > 0);
outStream.Close();
inStream.Close();
Image image = Image.FromFile("d:\\name.png");

Request stream fail to write

I have to upload a large file to the server with the following code snippet:
static async Task LordNoBugAsync(string token, string filePath, string uri)
{
HttpWebRequest fileWebRequest = (HttpWebRequest)WebRequest.Create(uri);
fileWebRequest.Method = "PATCH";
fileWebRequest.AllowWriteStreamBuffering = false; //this line tells to upload by chunks
fileWebRequest.ContentType = "application/x-www-form-urlencoded";
fileWebRequest.Headers["Authorization"] = "PHOENIX-TOKEN " + token;
fileWebRequest.KeepAlive = false;
fileWebRequest.Timeout = System.Threading.Timeout.Infinite;
fileWebRequest.Proxy = null;
using (FileStream fileStream = File.OpenRead(filePath) )
{
fileWebRequest.ContentLength = fileStream.Length; //have to provide length in order to upload by chunks
int bufferSize = 512000;
byte[] buffer = new byte[bufferSize];
int lastBytesRead = 0;
int byteCount = 0;
Stream requestStream = fileWebRequest.GetRequestStream();
requestStream.WriteTimeout = System.Threading.Timeout.Infinite;
while ((lastBytesRead = fileStream.Read(buffer, 0, bufferSize)) != 0)
{
if (lastBytesRead > 0)
{
await requestStream.WriteAsync(buffer, 0, lastBytesRead);
//for some reasons didnt really write to stream, but in fact buffer has content, >60MB
byteCount += bufferSize;
}
}
requestStream.Flush();
try
{
requestStream.Close();
requestStream.Dispose();
}
catch
{
Console.Write("Error");
}
try
{
fileStream.Close();
fileStream.Dispose();
}
catch
{
Console.Write("Error");
}
}
...getting response parts...
}
In the code, I made a HttpWebRequest and push the content to server with buffering. The code works perfectly for any files under 60MB.
I tried a 70MB pdf. The buffer array has different content for each buffering. Yet, the request stream does not seem to be getting written. The bytecount also reached 70M, showing the file is properly read.
Edit (more info): I set the break point at requestStream.Close(). It clearly takes ~2 mins for the request stream to write in 60MB files but only takes 2ms for 70MB files.
My calling:
Task magic = LordNoBugAsync(token, nameofFile, path);
magic.Wait();
I am sure my calling is correct (it works for 0B to 60MB files).
Any advice or suggestion is much appreciated.

How to add an image from URL to Excel Worksheet via C#

Here is the goal:
1) Get image from URL, in this case Google Static Maps API
2) Insert this image into an Excel Worksheet. I am okay if I have to create (or use an existing) shape and set the background to the image. I am also okay inserting at specific cells. I can define the image size via the Google Static Maps API (see URL above) so it will always be known.
I am not entirely clear on how to do this WITHOUT saving the file directly to the file system first.
I currently have code like this which gets the image in a MemoryStream format:
public static MemoryStream GetStaticMapMemoryStream(string requestUrl, string strFileLocation)
{
try
{
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))
{
Byte[] lnByte = reader.ReadBytes(1 * 700 * 500 * 10);
using (FileStream lxFS = new FileStream(strFileLocation, FileMode.Create))
{
lxFS.Write(lnByte, 0, lnByte.Length);
}
MemoryStream msNew = new MemoryStream();
msNew.Write(lnByte, 0, lnByte.Length);
return msNew;
}
}
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
return null;
}
}
Note that in the middle of the above code, I write the image to the file system as well. I'd like to avoid this part if at all possible.
At any rate, my code can create a rectangle, call the above sequence which saves the image, and then grab the image and populate the background of the rectangle:
Excel.Shape shapeStaticMap = wsNew2.Shapes.AddShape(Office.MsoAutoShapeType.msoShapeRectangle, 0, 0, 700, 500);
string strFileLocation = #"C:\Temp\test.jpg";
MemoryStream newMS = GetStaticMapMemoryStream(strStaticMapUrl, strFileLocation);
shapeStaticMap.Fill.UserPicture(strFileLocation);
So the real problem here is that I'd like to skip the "write to file and then grab from file" back-and-forth. It seems like an unnecessary step, and I anticipate that it will also get messy with file permissions and what-not.
UPDATE
Okay, so I basically gave up and left it using a local file. That worked for a while, but now I'm trying to re-work this code to grab an image from a different source where I don't know the image size in advance. The method above requires me to know the SIZE of the image in advance. How do I modify the code above to use any image size dynamically?
Use this version of GetStaticMapMemoryStream:
public static MemoryStream GetStaticMapMemoryStream(string requestUrl)
{
try
{
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
var responseStream = response.GetResponseStream();
var memoryStream = new MemoryStream();
responseStream.CopyTo(memoryStream);
memoryStream.Position = 0;
return memoryStream;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}

The specified argument is outside the range of valid values - C#

I keep getting this error:
The specified argument is outside the range of valid values.
When I run this code in C#:
string sourceURL = "http://192.168.1.253/nphMotionJpeg?Resolution=320x240&Quality=Standard";
byte[] buffer = new byte[200000];
int read, total = 0;
// create HTTP request
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sourceURL);
req.Credentials = new NetworkCredential("username", "password");
// get response
WebResponse resp = req.GetResponse();
// get response stream
// Make sure the stream gets closed once we're done with it
using (Stream stream = resp.GetResponseStream())
{
// A larger buffer size would be benefitial, but it's not going
// to make a significant difference.
while ((read = stream.Read(buffer, total, 1000)) != 0)
{
total += read;
}
}
// get bitmap
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));
pictureBox1.Image = bmp;
This line:
while ((read = stream.Read(buffer, total, 1000)) != 0)
Does anybody know what could cause this error or how to fix it?
Thanks in advance
Does anybody know what could cause this error?
I suspect total (or rather, total + 1000) has gone outside the range of the array - you'll get this error if you try to read more than 200K of data.
Personally I'd approach it differently - I'd create a MemoryStream to write to, and a much smaller buffer to read into, always reading as much data as you can, at the start of the buffer - and then copying that many bytes into the stream. Then just rewind the stream (set Position to 0) before loading it as a bitmap.
Or just use Stream.CopyTo if you're using .NET 4 or higher:
Stream output = new MemoryStream();
using (Stream input = resp.GetResponseStream())
{
input.CopyTo(output);
}
output.Position = 0;
Bitmap bmp = (Bitmap) Bitmap.FromStream(output);

Read Http Request into Byte array

I'm developing a web page that needs to take an HTTP Post Request and read it into a byte array for further processing. I'm kind of stuck on how to do this, and I'm stumped on what is the best way to accomplish. Here is my code so far:
public override void ProcessRequest(HttpContext curContext)
{
if (curContext != null)
{
int totalBytes = curContext.Request.TotalBytes;
string encoding = curContext.Request.ContentEncoding.ToString();
int reqLength = curContext.Request.ContentLength;
long inputLength = curContext.Request.InputStream.Length;
Stream str = curContext.Request.InputStream;
}
}
I'm checking the length of the request and its total bytes which equals 128. Now do I just need to use a Stream object to get it into byte[] format? Am I going in the right direction? Not sure how to proceed. Any advice would be great. I need to get the entire HTTP request into byte[] field.
Thanks!
The simplest way is to copy it to a MemoryStream - then call ToArray if you need to.
If you're using .NET 4, that's really easy:
MemoryStream ms = new MemoryStream();
curContext.Request.InputStream.CopyTo(ms);
// If you need it...
byte[] data = ms.ToArray();
EDIT: If you're not using .NET 4, you can create your own implementation of CopyTo. Here's a version which acts as an extension method:
public static void CopyTo(this Stream source, Stream destination)
{
// TODO: Argument validation
byte[] buffer = new byte[16384]; // For example...
int bytesRead;
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
destination.Write(buffer, 0, bytesRead);
}
}
You can just use WebClient for that...
WebClient c = new WebClient();
byte [] responseData = c.DownloadData(..)
Where .. is the URL address for the data.
I use MemoryStream and Response.GetResponseStream().CopyTo(stream)
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
MemoryStream ms = new MemoryStream();
myResponse.GetResponseStream().CopyTo(ms);
byte[] data = ms.ToArray();
I have a function that does it, by sending in the response stream:
private byte[] ReadFully(Stream input)
{
try
{
int bytesBuffer = 1024;
byte[] buffer = new byte[bytesBuffer];
using (MemoryStream ms = new MemoryStream())
{
int readBytes;
while ((readBytes = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, readBytes);
}
return ms.ToArray();
}
}
catch (Exception ex)
{
// Exception handling here: Response.Write("Ex.: " + ex.Message);
}
}
Since you have Stream str = curContext.Request.InputStream;, you could then just do:
byte[] bytes = ReadFully(str);
If you had done this:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(someUri);
req.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
You would call it this way:
byte[] bytes = ReadFully(resp.GetResponseStream());
class WebFetch
{
static void Main(string[] args)
{
// used to build entire input
StringBuilder sb = new StringBuilder();
// used on each read operation
byte[] buf = new byte[8192];
// prepare the web page we will be asking for
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(#"http://www.google.com/search?q=google");
// execute the request
HttpWebResponse response = (HttpWebResponse)
request.GetResponse();
// we will read data via the response stream
Stream resStream = response.GetResponseStream();
string tempString = null;
int count = 0;
do
{
// fill the buffer with data
count = resStream.Read(buf, 0, buf.Length);
// make sure we read some data
if (count != 0)
{
// translate from bytes to ASCII text
tempString = Encoding.ASCII.GetString(buf, 0, count);
// continue building the string
sb.Append(tempString);
}
}
while (count > 0); // any more data to read?
// print out page source
Console.WriteLine(sb.ToString());
Console.Read();
}
}
For all those cases when your context.Request.ContentLength is greather than zero, you can simply do:
byte[] contentBytes = context.Request.BinaryRead(context.Request.ContentLength);

Categories