The System.Drawing.Image has the easy to use methods for FromFile and ToFile. What is the equivalent for the Silverlight BitmapImage? I am trying to load and save a jpeg image as part of a unit test. The bytes must match exactly for it to pass. Here is my current guess:
//I am not sure this is right
private BitmapImage GetImage(string fileName)
{
BitmapImage bitmapImage = new System.Windows.Media.Imaging.BitmapImage();
using (Stream imageStreamSource = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
bitmapImage.BeginInit();
bitmapImage.StreamSource = imageStreamSource;
bitmapImage.EndInit();
}
return bitmapImage;
}
private void SaveImage(BitmapImage bitmapImage, string file)
{
//How to do this?
}
An in-browser Silverlight application cannot open a file using a filename. You would need it run out-of-browser with elevated trust to do that.
Silverlight has no built-in image encoding so you can't take the contents of a bitmap (BTW you would need to be using WriteableBitmap to be able to access the raw image).
You find something you need in Image Tools.
From MSDN link, use the ctor overload which takes in a URI or
BitmapImage myBitmapImage = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(#"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg");
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.EndInit();
//set image source
myImage.Source = myBitmapImage;
To save the image to disk, you'd need the specific encoder e.g. JpegBitmapEncoder
Related
I have the following function to get BitmapImage of file.
public static BitmapImage GetThumbnail(string filePath)
{
ShellFile shellFile = ShellFile.FromFilePath(filePath);
BitmapSource shellThumb = shellFile.Thumbnail.ExtraLargeBitmapSource;
BitmapImage bImg = new BitmapImage();
PngBitmapEncoder encoder = new PngBitmapEncoder();
MemoryStream memoryStream = new MemoryStream();
encoder.Frames.Add(BitmapFrame.Create(shellThumb));
encoder.Save(memoryStream);
bImg.BeginInit();
bImg.StreamSource = memoryStream;
bImg.EndInit();
return bImg;
}
When I get Video's Thumbnail it always works.
When I get Presentation (pptx) Thumbnail it doesn't work properly (I have no idea when it does and when it doesn't).
For example, I have 2 files in directory:
And this is how it looks in my program - 1 is ok and 1 isn't (sometimes both are ok, and sometimes both aren't):
I would appreciate if you could tell me what's the problem or maybe give me another way of getting the Thumbnail that will not fail...
p.s.
I would like to remind that with video files it works 100% fine (.mp3, .mp4, .wmv - thats what I tested)
Since I wanted to get pptx thumbnail, I came up with the following solution:
1. I extracted the thumbnail using DotNetZip
2. I got the thumbnail which is located in docProps directory
3. I extracted the thumbnail to memoryStream
4. I converted the memoryStream to BitmapImage and returned it.
here's the code:
public static BitmapImage GetPPTXThumbnail(string filePath)
{
using (ZipFile zip = ZipFile.Read(filePath))
{
ZipEntry e = zip["docProps/thumbnail.jpeg"];
BitmapImage bImg = new BitmapImage();
MemoryStream memoryStream = new MemoryStream();
bImg.BeginInit();
e.Extract(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
bImg.StreamSource = memoryStream;
bImg.EndInit();
return bImg;
}
}
Cant fail with this solution, this solution is only to get PPTX Thumbnail, I assume it works with all office xml files such as docx, xlsx, etc...
I have:
WriteableBitmap bmp;
I basicly want to save it into a file on the disk like the following:
C:\bmp.png
I read some forums which mentions to read:
bmp.Pixels
and save those pixels into a Bitmap then use Bitmap.SaveImage() function. However, I can't access any Pixels. Apperantly my WriteableBitmap does not have any property named Pixels.
I use .NET Framework 4.0.
Use your WriteableBitmap's clone and use this function as below:
CreateThumbnail(filename, _frontBitmap.Clone());
...
void CreateThumbnail(string filename, BitmapSource image5)
{
if (filename != string.Empty)
{
using (FileStream stream5 = new FileStream(filename, FileMode.Create))
{
PngBitmapEncoder encoder5 = new PngBitmapEncoder();
encoder5.Frames.Add(BitmapFrame.Create(image5));
encoder5.Save(stream5);
}
}
}
I'm having some trouble reading JPEG files in my class. I need to load metadata and bitmap from a JPEG file. So far, I have this:
public void Load()
{
using (Stream imageStream = File.Open(this.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
BitmapDecoder decoder = new JpegBitmapDecoder(imageStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
BitmapSource source = decoder.Frames[0];
// load metadata
this.metadata = source.Metadata as BitmapMetadata;
// prepare buffer
int octetsPerPixel = source.Format.BitsPerPixel / 8;
byte[] pixelBuffer = new byte[source.PixelWidth * source.PixelHeight * octetsPerPixel];
source.CopyPixels(pixelBuffer, source.PixelWidth * octetsPerPixel, 0);
Stream pixelStream = new MemoryStream(pixelBuffer);
// load bitmap
this.bitmap = new Bitmap(pixelStream); // throws ArgumentException
}
this.status = PhotoStatus.Loaded;
}
But the Bitmap constructor throws an ArgumentException when trying to create a Bitmap instance from a stream.
The documentation says:
System.ArgumentException
stream does not contain image data or is null.
-or-
stream contains a PNG image file with a single dimension greater than 65,535 pixels.
I'm not sure, what I did wrong. Can you please help me?
You're using the Bitmap constructor which is usually used to load an image file in a known format - JPEG, PNG etc. Instead, you've just got a bunch of bytes, and you're not telling it anything about the format you want to use them in.
It's not clear why you want to use BitmapDecoder and BitmapSource at all - why aren't you just using:
Stream imageStream = File.Open(this.FilePath, FileMode.Open,
FileAccess.Read, FileShare.Read));
this.bitmap = new Bitmap(imageStream);
Note that you mustn't use a using statement here - the Bitmap "owns" the stream after you've called the constructor.
Aside from all of this, you seem to be trying to mix WPF and WinForms ideas of images, which I suspect is a generally bad idea :(
I have found how to do this in .NET 4.0, but I think JpegBitmapEncoder doesn't exist in Silverlight:
MemoryStream memStream = new MemoryStream();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imageC));
encoder.Save(memStream);
var bytes = memStream.GetBuffer();
How can I convert an image to bytes[] in silverlight?
UPDATE:
I have a Contact model, which has a Photo property. Whenever I add a new Contact, I would like to load a local default Image and convert it and set the Photo property to it.
var bitmapImage = new BitmapImage
{
UriSource = new Uri("pack://application:,,,/xxx;component/Images/default.JPG")
};
var image = new Image{Source = bitmapImage};
Is this the correct way to load an image in first place?
Use
myImage.Save(memStream, ImageFormat.Jpeg);
return memStream.ToArray();
UPDATE
OK it turns out that the image is a BitmapImage.
It seems that BitmapImage does not expose the functionality to save the image. The solution is to get the image from the embedded resource:
Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourcePath);
byte[] buffer = new byte[s.Length];
s.Read(buffer, 0, buffer.Length);
Have a look at this library: Imagetools
It contains some nice utilities and jpg and png encoders,
Here is the problem.
I want to open a file from local drives, then make it into a WritableBitmap so i can edit it.
But the problem is, i cannot create a WritableBitmap from Uri or something like that. Also i know how to open a file into BitmapImage but i cannot figure out how to open a file as WritableBitmap.
Is there way to open a file directly into a WritableBitmap,if there is not, is there a way to convert a BitmapImage to a WritableBitmap?
Thanks guys.
You can load your image file into a BitmapImage and use that as a source for your WriteableBitmap:
BitmapImage bitmap = new BitmapImage(new Uri("YourImage.jpg", UriKind.Relative));
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmap);
I'm no expert and don't have immediate access to intellisense and whatnot, but here goes...
var fileBytes = File.ReadAllBytes(fileName);
var stream = new MemoryStream(fileBytes);
var bitmap = new BitmapImage(stream);
var writeableBitmap = new WritableBitmap(bitmap);
Even if not a perfect example this should be enough to point you in the right direction. Hope so.
In Silverlight 5 you can use below method to open file from local disk and convert it to BitmapImage and make it in to WriteableBitmap;
OpenFileDialog dlg = new OpenFileDialog();
dlg.Multiselect = false;
dlg.ShowDialog();
byte[] byteArray = new byte[] { };
if (dlg.File == null) return;
BitmapImage bi = new BitmapImage();
bi.CreateOptions = BitmapCreateOptions.None;
// bi.UriSource = new Uri(#"C:\Users\saw\Desktop\image.jpg", UriKind.RelativeOrAbsolute);
bi.SetSource(dlg.File.OpenRead());
WriteableBitmap eb=new WriteableBitmap(bi);
setting new Uri gave me error (Object reference not set to an instance of an object) while trying to create WriteableBitmap