I believe with JPGs, the width and height information is stored within the first few bytes. What's the easiest way to get this information given an absolute URI?
First, you can request the first hundred bytes of an image using the Range header.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Set(HttpRequestHeader.UserAgent, "Range: bytes=0-100");
Next, you need to decode. The unix file command has a table of common formats, and the locations of key information. I'd suggest installing Cygwin and taking a look at /usr/share/file/magic.
For gif's and png's, you can easily get the image dimensions from the first 32 bytes. However, for JPEGs, #Andrew is correct in that you can't reliably get this information. You can figure out if it has a thumbnail, and the size of the thumbnail.
The get the actual jpeg size, you need to scan for the start of frame tag. Unfortunately, one can't reliably determine where this is going to be in advance, and a thumbnail could push it several thousand bytes into the file.
I'd recommend using the range request to get the first 32 bytes. This will let you determine the file type. After which, if it's a JPEG, then download the whole file, and use a library to get the size information.
I am a bit rusty at this, but with jpeg, it might not be as simple as it seems. Jpeg has a header within each segment of data which has its own height / width and resolution. jpeg was not designed to be streamed easily. You might need to read the entire image to find the width and height of each segment within the jpeg to get the entire width and height.
If you absolutely need to stream an image consider changing to another format which is easier to stream, jpeg is going to be tough.
You could do it if you can develop a server side program that would seek forward and read the header of each segment to compute the width and height of the segment.
It's a bit Heath Robinson, but since browsers seem to be able to do it perhaps you could automate IE to download the image within a webpage and then interrogate the browser's DOM to reveal the dimensions before the image has finished downloading?
Use this code:
public static async Task<Size> GetUrlImageSizeAsync(string url)
{
try
{
var request = WebRequest.Create(url);
request.Headers.Set(HttpRequestHeader.UserAgent, "Range: bytes=0-32");
var size = new Size();
using (var response = await request.GetResponseAsync())
{
var ms = new MemoryStream();
var stream = response.GetResponseStream();
stream.CopyTo(ms);
var img = Image.FromStream(ms);
size = img.Size;
}
return size;
}
catch
{
return new Size();
}
}
Related
I try to save my images on my server, but I can't let my server save file and virus because of that I want to get image content as pixels of rgb and after that I create image by myself.
I can't use bitmap (or other type in C# like bitmapImage, ... etc) and I don't know how I can do this with sixlabors.ImageSharp.
I have some code that I tried but I can't implement the exact logic that I want (code shown here):
[HttpPost("[action]")]
public async Task<IActionResult> Get([FromForm] ImageFormat file)
{
await using var memoryStream = new MemoryStream();
await file.File.CopyToAsync(memoryStream);
IImageFormat format;
using (var image = Image.Load(memoryStream.ToArray(), out format))
{
using (var output = new MemoryStream())
{
image.Save(output, format);
var responseType = format.Name.ToLower();
return File(output.ToArray(), "application/octet-stream", file.File.FileName);
}
}
return null;
}
Can anybody help me with this problem?
i don't see a reason to convert image into image: there are several format zip-algorythms etc.wich you have to support in that case. example jpg is not bitmap, there is convertion issue - quality of image becomes less each conversion time. Image itself is not executable - it can be used only as container for virus body, can't harm your OSystem itself, another executable part should works somewhere.
But even if you would like to store images on disk, in other format - you can convert image to base64 text (one line of code, like example) - it less harmful and well known way to work with any file type. you can zip image by cszip, you can change file name and extension to hide file type.
I don't see a reasson to convert one image to another for this scenario/task.
I am working on Universal Windows Applications, in my current project I used Unified Communications Web API (UCWA) to display the skype user status it's working fine but when I am trying to display the skype user photo at that time I got stuck.
I followed below link to display the photo
https://msdn.microsoft.com/en-us/skype/ucwa/getmyphoto
I got response code of 200 OK for my GET request but I don't know how to display the image from my response.
Please tell me how to resolve it.
-Pradeep
I got Result, After getting HTTP Response then I am converting those response content to stream type by using this below line.
var presenceJsonStr = await httpResponseMessage.Content.ReadAsStreamAsync();
This is the code to display the image
var photo = await AuthenticationHelper.Photo();
// Create a .NET memory stream.
var memStream = new MemoryStream();
// Convert the stream to the memory stream, because a memory stream supports seeking.
await photo.CopyToAsync(memStream);
// Set the start position.
memStream.Position = 0;
// Create a new bitmap image.
var bitmap = new BitmapImage();
// Set the bitmap source to the stream, which is converted to a IRandomAccessStream.
bitmap.SetSource(memStream.AsRandomAccessStream());
// Set the image control source to the bitmap.
imagePreivew.ImageSource = bitmap;
Assuming you put an Accept header specifying an image type, you should be able to look at the Content-Length header to determine if the user has an image set on the server. If the length is zero you should consider providing a default image to be displayed. If not, I would suggest taking a look at Convert a Bitmapimage into a Byte Array and Vice Versa in UWP Platform as you should treat the response body as a byte array with its length defined by the Content-Length header.
If for some reason no Accept header was provided, the response body is not an image/* type, and looks like a string then you might be dealing with a Base64 encoded image. This case should be much less likely to deal with, but if you need advice I would suggest looking at Reading and Writing Base64 in the Windows Runtime.
You can directly use the URL generated for the user photo resource. Just set the URL of the image as the source of the Image container. You application would load it automatically.
This is my first question, so I hope to provide what it needs to get a decent answer.
I want to send an image received by a webcam over a serial link.
The Image is converted into a byte array and then written to the serial port.
The first issue I ran into was, that when I tried to send the image, it lead to a TimeoutException. Looking at the lenght of the byte array, it showed me around 1 MB of data that needs to be transmitted. Shrinking the actual size of the image resulted in an much faster transmission, but afterwards the image was way too small.
The second isuue was when I tried to compress the image. Using different methods, the size of transmission was always excactly the same.
I hope you can help me find a way to improve my implementation, so that the transmission only takes a few seconds while still maintaining reasonable resolution of the image. Thanks.
Specific Information
Webcam Image
The image from the webcam is received by the AForge library
The image is handled as a Bitmap
(Obviously) it doesn't transmit every frame, only on the click of a button
Serial Port
The port uses a baud rate of 57600 bps (defined by hardware beneath)
The WriteTimeout-value is set to 30s, as it would be unacceptable to wait longer than that
Text transmission works with default values on the SerialPort-item in a WinForm
Image Manipulation
I used different approaches to compress the image:
Simple method like
public static byte[] getBytes(Bitmap img)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] output = ms.toArray();
ms.Dispose();
return output;
}
as well as more advanced methods like the one posted here. Not only with Encoder.Quality but also with Encoder.Compression.
My Application
private void btn_Send(...)
{
Bitmap currentFrame = getImageFromWebcam();
//Bitmap sendFrame = new Bitmap(currentFrame, new Size(currentFrame.Width/10, currentFrame.Height/10));
Bitmap sendFrame = compressImage(currentFrame);
byte[] data = getBytes(sendFrame);
serialPort.Write(data, 0, data.Lenght);
}
C Hanging the timeout property of the serial port would solve the timeout issue. How is show in this link https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.writetimeout(v=vs.110).aspx. File compression works by looking at blocks of data and associating similar blocks with each other for a given segment of blocks. If your image is too unique it will not compress depending on the compression software being used.
I am still very much learning ASP.NET using c# and Webmatrix. I have put together a photography competition site but can't quite find an ideal way of uploading images. I don't see the point of uploading images greater than 1200x900 (projectors maximum resolution) so want to make sure images are small as possible.
I am using tag and checking he image size. If it's too big I am using 'ImageResizer' to resize the image when saving. The only way I know to check the size is to convert the 'HttpPostedFileBase' file into an image using System.Drawing.Image. But when the image is 36Mpixels (it is a photography club) this is taking an age just to read the height and width properties. Can I just load the first x bytes to read the properties or do I have to read the whole image?
The second reason I am converting to an image is to extract the exif data. Again is there an easier and quicker way to read the exif data?
I hope my question makes sense this is all a bit new to me.
simplified code:
HttpPostedFileBase uploadedFile = Request.Files[0];
using (System.Drawing.Image image = System.Drawing.Image.FromStream(uploadedFile.InputStream, true, true))
{
string Exif;
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
try{
Exif = encoding.GetString(image.GetPropertyItem(36867).Value);
}
catch
{
Exif="";
}
if (image.Width <Convert.ToInt32(MaxWidth) && image.Height <Convert.ToInt32(MaxHeight))
{
// SAVE IMAGE AS IS
image.Save(fileSavePath);
// LOAD IMAGE DETAILS WITH EXIF
db.Execute("INSERT INTO CompImages (ImageTitle,CompID,GroupID,ClubID,FileName,UserID,ExifDate) VALUES(#0,#1,#2,#3,#4,#5,#6)",ImageTitle,CompID,GroupID,ClubID,fileName,WebSecurity.CurrentUserId,DateTaken);
}
else
{
// LOAD IMAGE DETAILS WITH EXIF
db.Execute("INSERT INTO CompImages (ImageTitle,CompID,GroupID,ClubID,FileName,UserID,ExifDate) VALUES(#0,#1,#2,#3,#4,#5,#6)",ImageTitle,CompID,GroupID,ClubID,fileName,WebSecurity.CurrentUserId,DateTaken);
// RESIZE IMAGE
ImageResizer.ImageJob iF = new ImageResizer.ImageJob(image, "~/UpImages/"+CompID+"/"+fileName, new ImageResizer.ResizeSettings(
"width="+MaxWidth+";height="+MaxHeight+";format=jpg;mode=max"));
iF.CreateParentDirectory = true; //Auto-create the uploads directory.
iF.Build();
}
}
The only way I know to check the size is to convert the
'HttpPostedFileBase' file into an image using System.Drawing.Image.
You could also checkout the ContentLength property directly:
int uploadedFileSize = uploadedFile.ContentLength;
The second reason I am converting to an image is to extract the exif
data. Again is there an easier and quicker way to read the exif data?
I am not aware of a built-in class in the BCL that would allow you to read EXIF information without loading the image in memory but you could use some third party library like this one: http://www.codeproject.com/Articles/36342/ExifLib-A-Fast-Exif-Data-Extractor-for-NET-2-0
i'm trying to make my gif images animated. i've found some very suitable piece of code here: http://tomlev2.wordpress.com/2011/03/27/wpf-display-an-animated-gif-image/
but i faced with next problems: on windows 2003 server, windows xp it is not possible to obtain gif metadata (WIC is available for vista, win7...). and i need to get frame width and height, disposal method and some other data. gif images are obtained through Uri. how can i get necessary data knowing only Uri and without saving gifs on disk?
You can load the image in to an Image object from a stream, and you can create a stream using the URL. This would allow you to create an Image object without saving to disk, and from the object you can get info such as width and height etc. Would this help?
E.g.
Image image;
WebRequest request = WebRequest.Create("http://<insert URL here >");
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
image = Image.FromStream(stream);
}
}
// Use image here...