C#: Remote Image size without downloading it - c#

I have an image's URL. Is it possible to find out its size(in bytes) and dimensions without downloading the complete image?
EDIT
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "HEAD";
HttpWebResponse resp = (HttpWebResponse)(req.GetResponse());
System.Console.WriteLine(resp.ContentLength);
I have written this code. It works fine for first two time and the third time it gives WebException i.e. "operation timed out" irrespective of the image url. Is there something that I am missing here?

No, this is not possible.
You can get its size in bytes by issuing an HTTP HEAD command (instead of a GET); this will return the HTTP headers only, omitting the contents.
The HTTP header of an image will return its size in bytes:
Content-length: 6372
Content-type: image/jpeg
but not its dimensions.
So you'll have to do an HTTP GET...

Basically, yes. If you know what kind of image it is e.g. png or jpg (you can also get this information from the MIME-type of your HTTP-connection, you can download the header only and read the image extents from there. Also see this related question:
What is the header size of png, jpg/jpeg, bmp, gif and other common graphics format?

Related

.net Compact Framework 2.0 - OutOfMemory Exception When downloading an image

Im creating software for a Symbol MC75A using c# .net CF 2.0. We scan a barcode and it returns stock information but i am trying to add a feature that gets an image from a url. Each scan refreshes the screen with new data from database and also gets the image from the new url. It scans a few barcodes and returns maybe 4/5 images without issue then all of a sudden a OutOfMemoryException occurs. The code im using to Get Image is:
public Bitmap GetImage(string URL)
{
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL);
myRequest.Method = "GET";
myRequest.AllowWriteStreamBuffering = false;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(myResponse.GetResponseStream());
myResponse.Close();
return bmp;
}
Called by:
pbImage.Image = GetImage(ProductImage);
pbImage.SizeMode = PictureBoxSizeMode.StretchImage;
I have tried to dispose of image before each new GET with pbImage.Image.Dispose() but still getting the same exception. The image sizes are between 100KB and 550KB. Whether it makes a difference the images sizes are always over 1000px each side.
Am i missing the correct way of disposing before re-getting or is it somehow caching all these images which then creates an outofMemory exception?
I have found my solution herer:
OutOfMemoryException loading big image to Bitmap object with the Compact Framework
It seems it is the system.drawing when decompressing the 2000px image it is creating an uncompressed image giving a larger size on the memory hense the exception. The solution shows a way to obtain a thumbnail of the image rather than the whole image.
Thanks for your help again.
Just incase someone has access to the image location. A better work around for me was to creat a webpage named resize.aspx and have the picture box populate from the page with the image filename as a parameter. Now that page (being on the server in the same location as the images) was able to resize the image and return a small 300x300px image. Seemed to be the best solution i could think of. This can also work for images at any url if you pass the full url of the image into another page and that page returns the required thumbnail.

Failure to convert JFIF/Jpeg from CardDAV server's response

I'm using C#'s WebClient to download and image from a CardDav server and when I look at Fiddler the response from the server will contain a jpeg file, I can even preview the response as an image on Fiddler and it looks fine.
I've tried all the c# conventional methods to convert byte arrays to image/bitmap and none of them work, they throw an "invalid argument exception" exception.
FIDDLER response preview:
Content-Type: image/jpeg
Cache-Control: max-age=32000000, private
Content-Disposition: attachment
Content-Length: 46341
ÿØÿà JFIF ÿÛ C ÿÛ CÿÀ œ ² ÿÄ
ÿÄ µ } !1AQa"q2‘¡#B±ÁRÑð$3br‚
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖ×ØÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ
ÿÄ µ w !1AQaq"2B‘¡±Á #3RðbrÑ
$4á%ñ&'()56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖ×ØÙÚâãäåæçèéêòóôõö÷øùúÿÚ ? ÿ ?ú (  €
(Ü>~οiïX|9øà=[âŒ5ËK(4}È{¥k¸¯®ÃÃ$É3YÙéú^©ªêw0E2iºN™¨jw¾M•œó êì…ÿ &ý©ièüq{¯jºÁµøo«Ieâ_
øâË]³ñµäz–½¦Þbøoû1µ©e¹»ðÖ­§é­£Í£^ëË¢6¡·¥ëú^‘š‹Kvíøú
®Á¼:f™û,káü¿þ(~Ô><ñ=æƒðÏÂÞ4Ó"ø/¥Úivþ¹Ôõ=w^Ò¼A¯yö+¢^Xj?b:Ô–/­ØCe|šVÛäµµI÷ð«öcý†>3|hý®¼9û2.™¦øOÆÖþ3—C½»ñî­]ø&ÛZЊê'Iñ,iot¶wðÂ>ݦ]Åm©­Œ—\XGx¯fvM¾‰¿¸ôý™?fKŸÙãàφ¾~Îqi¿ üsñ7Bñ'íà¿|HøÉ¢i%øà8í<;âü>Õ<3â2ø]|Cðźèþ›sqáýà³ð]íí‘Õ¾ÚéwÊ´\d£Ì›M'¦­ýCk?Äÿ
ø‡Æ^"¸øÉñ<|ÃÚ7ˆuÙüpøû7ŽnõO é/™l-õýGâÑ黨øœk~ ¹Ò5]2ïQ“Á^Ò5“EƒW’æ![•Z|Òv²{ëÑ¿.þ›þw_ðUOØ+Dz'í6“ÿ ÷„-´¿‰vkã
ø/ៈu xÃú•êé>ðä:®¥¿¾žâK[ˆàžðIu}qò=î©ró]?Dd¤®¿¯ëüÀýý™¿à߯|Tý›ü¯|cÅ?
Format: JPEG
46,341 bytes
178w x 156h
1.67 bytes/px
96 dpi
Baseline
Subsample#4:4:4 (non-opt)
APP0 Data (14 bytes)
[JFIF1.1]
Aspect: 1:1
HuffmanTables: 4
SOLUTION
It seems like in my WebClient routine I was pushing some necessary headers that caused the image to be returned in a strange encoding, now I'm pushing only "User-Agent" and "Authorization" and the response can be decoded to image perfectly.
It seems like in my WebClient routine I was pushing some unnecessary headers that caused the image to be returned in a strange encoding, now I'm pushing only "User-Agent" and "Authorization" and the response can be decoded into an image perfectly.

Get Size of Image File before downloading from web

I am downloading image files from web using the following code in my Console Application.
WebClient client = new WebClient();
client.DownloadFile(string address_of_image_file,string filename);
The code is running absolutely fine.
I want to know if there is a way i can get the size of this image file before I download it.
PS- Actually I have written code to make a crawler which moves around the site downloading image files. So I doesn't know its size beforehand. All I have is the complete path of file which has been extracted from the source of webpage.
Here is a simple example you can try
if you have files of different extensions like .GIF, .JPG, etc
you can create a variable or wrap the code within a Switch Case Statement
System.Net.WebClient client = new System.Net.WebClient();
client.OpenRead("http://someURL.com/Images/MyImage.jpg");
Int64 bytes_total= Convert.ToInt64(client.ResponseHeaders["Content-Length"])
MessageBox.Show(bytes_total.ToString() + " Bytes");
If the web-service gives you a Content-Length HTTP header then it will be the image file size. However, if the web-service wants to "stream" data to you (using Chunk encoding), then you won't know until the whole file is downloaded.
You can use this code:
using System.Net;
public long GetFileSize(string url)
{
long result = 0;
WebRequest req = WebRequest.Create(url);
req.Method = "HEAD";
using (WebResponse resp = req.GetResponse())
{
if (long.TryParse(resp.Headers.Get("Content-Length"), out long contentLength))
{
result = contentLength;
}
}
return result;
}
You can use an HttpWebRequest to query the HEAD Method of the file and check the Content-Length in the response
You should look at this answer: C# Get http:/…/File Size where your question is fully explained. It's using HEAD HTTP request to retrieve the file size, but you can also read "Content-Length" header during GET request before reading response stream.

HttpHandler to render a png from an array of bytes

Okay, this should be simple, but I just can't get it to work. I have an array of bytes, read from a png file. I'm trying to write a (very) simple HttpHandler to render the image:
context.Response.AddHeader("Content-Type", "image/png")
context.Response.BinaryWrite(bytes)
context.Response.End()
When I open the page in a browser, I just get gibberish,
�PNG IHDR���X��sRGB���gAMA�� �a pHYs���o�d` ...
It's obviously something with the header information I'm doing wrong. Any suggestions?
Try using the ContentType property instead of AddHeader:
context.Response.ContentType = "image/png";
...
Two more diagnostics:
If you use "save" in the browser and save it to a png file, does that render properly?
Use Wireshark to see what's really coming back in the response (which exact bytes etc)

How do i URL rewrite an image properly? C# ASP.NET

I tried several ways to URL rewrite. The first way the image mime was clobbered and was consider an octet stream which didnt allow me to view the image in a browser (unless it was using img src). The 2nd way i wasnt convince it worked. Firefox displayed the img but said the length was 0 (i think it only worked bc it was in my cache).
How do i properly rewrite the image /abc/id/title.png to the internal location /static/user/name/id.png
In ASP.NET I might do something like this:
Response.Clear();
Response.ContentType = profile.AvatarMimeType;
Response.BinaryWrite(profile.Avatar.ToArray());
Where profile.AvatarMimeType is an appropriate mime type for a gif, jpeg, or png.
And where profile.Avatar.ToArray() is a binary content from the db sent out as an array of data!

Categories