I've searched here for help with this, but nothing quite matches what I need. I have an image that gets uploaded, and I'd like to change the size before it gets saved to azure.
So currently my code is:
public ActionResult UserDetails(HttpPostedFileBase photo)
{ var inputFile = new Photo()
{
FileName = photo.FileName,
Data = () => photo.InputStream
};
//then I save to Azure
How would I change the photo.InputStream to 100x 100 px for example?
Here is how I do it:
byte[] imageBytes;
//Of course image bytes is set to the bytearray of your image
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
using (Image img = Image.FromStream(ms))
{
int h = 100;
int w = 100;
using (Bitmap b = new Bitmap(img, new Size(w,h)))
{
using (MemoryStream ms2 = new MemoryStream())
{
b.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);
imageBytes = ms2.ToArray();
}
}
}
}
From there, I use a MemoryStream to upload. I use blob storage and use the UploadFromStreamAsync to load to blob.
This is a basic view of it.
Related
I cannot decode images back from their encoded form as a (Jpeg) byte array retrieved from my database to be used as image sources for my WPF application.
The code I am using to encode them as a Jpeg byte array is as follows:
public byte[] bytesFromBitmap(BitmapImage bit)
{
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bit));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
This is taking my Image taken directly from a webpage and assigned to an Image control like so:
var img = new BitmapImage(new Uri(entity.Image.ImageSrc)); //the entity has been saved in my DB, having been parsed from html
pbImage.Source = img;
This works just fine, I encode the BitmapImage and it saves just fine. But when I retrieve it from the DB and try to display it in another window, I cannot get it to work after trying every example I can see online - all either render nothing, or a black box or a visual mess not at all similar to the image I encoded.
Neither of the following have worked for me:
public BitmapSource GetBMImage(byte[] data)
{
using (var ms = new MemoryStream(data))
{
JpegBitmapDecoder decoder = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource frame = decoder.Frames[0];
return frame;
}
}
public static BitmapImage ImageFromBytes(byte[] imageData)
{
if (imageData == null)
{
return null;
}
else
{
var image = new BitmapImage();
using (var mem = new MemoryStream())
{
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
} //this throws a 'No imaging component suitable to complete this operation was found' exception
Among other uses of memory streams and decoders I just can't get this to work - can anyone help?
I am copying all images from my device to directory. While copying the images I am getting this error Operation not permitted on IsolatedStorageFileStream.
Here is my code to copy the files.
MediaLibrary m = new MediaLibrary();
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.DirectoryExists("ImagesZipFolder"))
{
deleteFileFolder("ImagesZipFolder");
}
if (!store.DirectoryExists("ImagesZipFolder"))
{
store.CreateDirectory("ImagesZipFolder");
foreach (var picture in m.Pictures)
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder/" + picture.Name, FileMode.CreateNew, store))
{
BitmapImage image = new BitmapImage();
image.SetSource(picture.GetImage());
byte[] bytes = ConvertToBytes(image);
stream.Write(bytes, 0, bytes.Length);
}
}
}
}
Here is my ConvertToBytes method.
public byte[] ConvertToBytes(BitmapImage bitmapImage)
{
byte[] data = null;
WriteableBitmap wBitmap = null;
using (MemoryStream stream = new MemoryStream())
{
wBitmap = new WriteableBitmap(bitmapImage);
wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
//data = stream.GetBuffer();
data = stream.ToArray();
DisposeImage(bitmapImage);
return data;
}
}
Basically what I am trying is to create a zip file of all images. I have total 222 images in my device. So how can I solve this issue ? How can I create a zip of this images?
Most probably this is due to the concurrent access to the file
you can refer to the link:
Operation not permitted on IsolatedStorageFileStream. error
I checked your code and it seems to be working (providing there's no error in DisposeImage() method) There is no OperationNotPermittedException occuring. However, if there is error in your code, then it can only be because of deleteFileFolder("ImagesZipFolder") line. Can you give me the snippet so that I can study it further. I m posting the working code... I have replaced that method with simple predefined one--
MediaLibrary m = new MediaLibrary();
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.DirectoryExists("ImagesZipFolder"))
{
store.DeleteDirectory("ImagesZipFolder");
}
if (!store.DirectoryExists("ImagesZipFolder"))
{
store.CreateDirectory("ImagesZipFolder");
foreach (var picture in m.Pictures)
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder/" + picture.Name, FileMode.CreateNew, store))
{
BitmapImage image = new BitmapImage();
image.SetSource(picture.GetImage());
byte[] bytes = ConvertToBytes(image);
stream.Write(bytes, 0, bytes.Length);
}
}
}
}
I am trying to convert bitmap Image to Byte array. I have select all the image by using MediaLibrary class and added it into a list of bitmap images. Here is my code
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.DirectoryExists("ImagesZipFolder"))
{
store.CreateDirectory("ImagesZipFolder");
for (int i = 0; i < imgname.Count(); i++)
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder\" + imgname[i], System.IO.FileMode.CreateNew, store))
{
byte[] bytes = null;
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap wBitmap = new WriteableBitmap(ImgCollection[i]);
wBitmap.SaveJpeg(ms, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
bytes = ms.GetBuffer();
stream.Write(bytes, 0, bytes.Length);
}
// byte[] bytes = Encoding.UTF8.GetBytes(imgname[i]);//new byte[ImgCollection[i].PixelWidth * ImgCollection[i].PixelHeight * 4];
// stream.Write(bytes, 0, bytes.Length);
}
}
}
else {
directory = true;
}
}
Basically what I am trying to do is, selecting all images or photo from device and create a zip file of that images. I was successful in creating a zip file of images. When I extract that file there is some images, but the problem is when I double click on image, I can't see that image. I think the problem is in reading the bytes of image. I am not getting what's wrong? Is my code is correct ?
Perhaps you can try the below. I know this code maintains the image, so if you have no luck using this, you may have a different issue.
// Convert the new image to a byte[]
ImageConverter converter = new ImageConverter();
byte[] newBA = (byte[])converter.ConvertTo(newImage, typeof(byte[]));
The ImageConverter is of the System.Drawing namespace.
Update:
http://msdn.microsoft.com/en-GB/library/system.windows.media.imagesourceconverter.convertto.aspx
You should be able to use this in place of the System.Drawing type I suggested.
There is no need to save the WriteableBitmap to a MemoryStream and then copy it to an IsolatedStorageFileStream. Just save the bitmap directly to the IsolatedStorageFileStream.
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(#"ImagesZipFolder\" + imgname[i], System.IO.FileMode.CreateNew, store))
{
WriteableBitmap wBitmap = new WriteableBitmap(ImgCollection[i]);
wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
}
This will allow you to save on memory as well. If you really want to save memory, you could reuse the WriteableBitmap.
I have the following code to convert image to base64:
private void btnSave_Click(object sender, RoutedEventArgs e)
{
StreamResourceInfo sri = null;
Uri uri = new Uri("Checked.png", UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
MemoryStream ms = new MemoryStream();
wb.SaveJpeg(ms, bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);
byte[] imageBytes = ms.ToArray();
base64 = System.Convert.ToBase64String(imageBytes);
}
And the following code to get Bitmap image form base 64:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes, 0, fileBytes.Length))
{
ms.Write(fileBytes, 0, fileBytes.Length);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(ms);
return bitmapImage;
}
}
So when i convert and deconvert it is blank.
I know that deconverter works, because, when i give him exact string:
string base64="iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAQAAABLCVATAAACH0lEQVR42q3WoZKrMBQGYGRkIpHEoY9DMrh1nUGtzxPcGV7gCsTaK3iBCqa2ipmrVqLrWrmytjL3nBwoEGD30ja/6JaSj/wp3SEIXjpUoB+Oeg0zpoR+NsyoDVOgi39cbYHAy4MQTc0wOYZepxRBUkn9UxxEiNnXxyYwd6w/438hSddHJilv1tqv664Shle1DeJaJihPV9uNQ+NWBRK2QVSr+GjtaFzOIpdjKFShnoY+Gv0N0u0OVLexY48NQ+68JchdpQu/o1piVMu6faJdwjNWIAYyl55bqGUtbndO53TzCIpUpCkdlEm+V3J3Ir8r3uops2+FkTmvx832IGJwN97xS/5Ti0LQ/WLwtbxMal2ueAwvc2c8CAgSJip5U4+tKHECMlUzq2UcA9EyROuJi6/71dtzWAfVcq0Jw1CsYh13kDDteVoirE+zWtLVinQ8ZAS5YlVlvRHWfi3pakUQL0OOwmp/W/vN6Gt5zBIkzEezxnCtMJsxDIECTYmhp3bej4HHzaalNMyAnzE0UBKp6Z1Do2pwd3JkAH6CxlTs/bZOZ661yMwhohDLQqREMWz8UAvWoUQleggehG5dSPUbv28GJlnKHGJsqPi7vuG/MGTyCGslOtkCOayrGOa/indajdudb6FUpXoepgiLHIIMriddyzrkMBhGAqlOH4U2hKCT2j0NdU8jFbzpZ3LQlh9srPqEQ1Y9lEP2CVa99KHvH8mnrGGdl9V9AAAAAElFTkSuQmCC";
Which is my Checked.png converted in online converter. It decompreses perfectly.
And this is my base64, which i get by converting:
"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"
My problem is that string which i get as base64 from my code - is incorrect *What i did wrong?*
What about trying:
public static BitmapImage base64image(string base64string)
{
byte[] fileBytes = Convert.FromBase64String(base64string);
using (MemoryStream ms = new MemoryStream(fileBytes))
{
Image streamImage = Image.FromStream(ms);
context.Response.ContentType = "image/jpeg";
streamImage.Save(context.Response.OutputStream, ImageFormat.Jpeg);
return streamImage;
}
}
I agree with Alexei that your code for reading the image in does look a little strange. I've recently written some code for a similar task that I was doing which might point you in the right direction:
string fileContent = null;
/* Check the file actually has some content to display to the user */
if (uploadFile != null && uploadFile.ContentLength > 0)
{
byte[] fileBytes = new byte[uploadFile.ContentLength];
int byteCount = uploadFile.InputStream.Read(fileBytes, 0, (int)uploadFile.ContentLength);
if (byteCount > 0)
{
fileContent = CreateBase64Image(fileBytes);
}
}
private string CreateBase64Image(byte[] fileBytes)
{
Image streamImage;
/* Ensure we've streamed the document out correctly before we commit to the conversion */
using (MemoryStream ms = new MemoryStream(fileBytes))
{
/* Create a new image, saved as a scaled version of the original */
streamImage = ScaleImage(Image.FromStream(ms));
}
using (MemoryStream ms = new MemoryStream())
{
/* Convert this image back to a base64 string */
streamImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return Convert.ToBase64String(ms.ToArray());
}
}
not an answer: more of a long comment ... OP states that decoding code works perfectly fine, also it looks suspicios. Also code assumed to be verified to work on PNG images, but saving code explicitly produces valid JPG with SaveJpeg call...
Your code that creates stream for reading looks strange - you create stream over existing byte array, than write the same bytes into that stream, and that pass that stream without seeking back to 0 to some method.
Potential fix (assuming BitampImage can accept JPG stream):
don't call Write at all as stream already have the bytes you want
set ms.Position = 0 after writing to the stream.
Note: I'm not sure if it is OK to dispose stream that is a source for BitmapImage, you may need to remove using too.
I am developing a program to grab images from four cameras and turn them into one picture only in style quad, 4 images in one. And it generate a .avi
AVIReader reader = new AVIReader();
List<byte[]> ImagemMainb = new List<byte[]>();
reader.Open(_rootPath + Path.GetFileName(_arqsCam01[i]));
while (reader.Position - reader.Start < reader.Length)
{
Bitmap aux = reader.GetNextFrame();
Bitmap r = new Bitmap(aux.Width * 2, aux.Height * 2, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
using (var g = Graphics.FromImage(r))
{
g.DrawImage(aux, new Rectangle(0, 0, aux.Width, aux.Height));
ImagemMainb.Add(ImageToByte(r));
}
}
reader.Close();
reader.Dispose();
And here is the method ImageToByte
public static byte[] ImageToByte(Image img)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
Using these codes takes too long to finish the process!
When I have a list of 84000 bitmaps in that case are 280 videos with frame rate = 5, size = 320x240, it takes forever.
Would have any problem in this code or have a better way?
i found the answer.
AVIReader reader = new AVIReader();
List<Bitmap> ImagemMain = new List<byte[]>();
reader.Open(_rootPath + Path.GetFileName(_arqs[0]));
while (reader.Position - reader.Start < reader.Length)
{
using (var aux = reader.GetNextFrame())
{
using (var r = new Bitmap(640, 480))
{
using (var g = Graphics.FromImage(r))
{
g.DrawImage(aux, new Rectangle(0, 0, aux.Width, aux.Height));
ImagemMain.Add((Bitmap)r.Clone());
}
}
}
}
Every video uploaded AVIWriter I open the file .avi and add bitmap.
With this is much more fast and does not take up almost no memory.