In my application I want to display some pictures (I need to have them stored in a list). I have problem with opening them. Firstly, I made a directory Images (using VS). Next I loaded pictures to this folder (also in VS).
I wanted to open one of them like here:
http://msdn.microsoft.com/en-us/library/aa970062.aspx
Stream imageStreamSource = new FileStream("Images\bulbOff.png", FileMode.Open, FileAccess.Read, FileShare.Read);
PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
And then while trying to run the program, I got:
XamlParseException
with hardly any information.
For sure the first line is causing the problem, because the problem disappears only when I delete it.
I tried to do it also like:
Uri myUri = new Uri("Images\bulbOff.png", UriKind.RelativeOrAbsolute);
PngBitmapDecoder decoder2 = new PngBitmapDecoder(myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource2 = decoder2.Frames[0];
with the same result.
I also tried to copy the image to main folder of app (in SolutionView). When I tried to get "\bulbOff.png" the result was the same.
When I tried to get "bulbOff.png" I got
XamlParseException
again, but with some info - there were hints that path could be wrong.
If you want to provide a BitmapImage...
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(#"..\Images\DocumentAccess_16x16.png", UriKind.Relative);
image.EndInit();
...where Images is a folder within your project.
Try to change your image and code to a jpg extension. Seriously.
Related
I am just learning c# and have been struggling to work with URIs in WPF. I've googled around a fair bit but not having much luck.
Essentially I'm trying to have a BitmapImage object stored as a property in a Car object. I then want to display the BitmapImage in an Image control on a WPF form.
The app is a simple app (it's for a Uni assignment), so no database, etc.
I have two methods of doing this. The first is that I'm preloading Car data from a text file, including the filename of the JPG I want to load. I have included the JPG in a directory called Files which is off the main directory where my source code and class files are. I have set the JPG file to 'Content' and 'Always copy'. When I run a Debug, it copies the Files directory and the JPG to the debug\bin directory.
My code creates a BitmapImage by referring to the JPG using a URI as follows;
BitmapImage myImage = new BitmapImage (new Uri("Files/" + Car.Imagefilename, UriKind.Relative);
Car.Image = myImage;
ImageControl.Source = myImage;
If I step through this code in the debugger, it sometimes works and displays the image, but most of the time it doesn't.
My second method is when a user creates a new Car. This method always works. In this one, I use a file dialog box (dlg) to select the image and use an absolute path.
BitmapImage myImage = new BitmapImage (new Uri(dlg.Filename, UriKind.Absolute);
Car.Image = myImage;
ImageControl.Source = myImage;
So....I can't work out why the first method doesn't work. I think it's got something to do with the relative reference, but I can't work out how to syntax that properly to work. I've tried using "pack:,,,", I've tried adding "component", I've tried an '#' before the "pack". I can't seem to find something that explains this simply.
Apologies if this is straight forward but it's doing my head in! Appreciate any pointers.
If the image files are located in a "Files" folder of your Visual Studio project, you should set their Build Action to Resource (and Copy to Output Directory to Do not copy), and load them by a Resource File Pack URI:
var image = new BitmapImage(new Uri("pack://application:,,,/Files/" + Car.Imagefilename));
Car.Image = image;
ImageControl.Source = image;
There is no need to copy the files anywhere. Images are loaded directly from the assembly.
First try to load the image file using its absolute path. For example if the images are stored in c:\projects\yourproject\files, then try using something like
BitmapImage myImage = new BitmapImage (new Uri("c:/projects/yourproject/files/carname.jpg", UriKind.Absolute);
If it works, what you are facing is an path calculation issue.
At this point you may either calculate the Absolute with reference to your executable using AppDomain.CurrentDomain.BaseDirectory at runtime or use App.Config to store the path and reference it from there.
Cheers
I'm trying to programmically delete a file, but the file is apparently being used by another process (which happens to be my program). Basically, the program loads images from a folder by using FromUri to create a Bitmap, which is then loaded into an Image array, which in turn becomes the child of a stackpanel. Not very efficient, but it works.
I've tried clearing the stackpanel's children, and making the images in the array null, but I'm still getting the IOException telling me that the file is being used by another process.
Is there some other way to remove the file from my application's processes?
it may be Garbage Collection issue.
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
File.Delete(picturePath);
In order to release an image file after loading, you have to create your images by setting the BitmapCacheOption.OnLoad flag. One way to do this would be this:
string filename = ...
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(filename);
image.EndInit();
Although setting BitmapCacheOption.OnLoad works on a BitmapImage that is loaded from a local file Uri, this is afaik nowhere documented. Therefore a probably better or safer way is to load the image from a FileStream, by setting the StreamSource property instead of UriSource:
string filename = ...
BitmapImage image = new BitmapImage();
using (var stream = File.OpenRead(filename))
{
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
}
Another way is to delete file. Load your file using FileStream class and release an file
through stream.Dispose();
it will never give you the Exception "The process cannot access the file '' because it is being used by another process."
using (FileStream stream = new FileStream("test.jpg", FileMode.Open, FileAccess.Read))
{
pictureBox1.Image = Image.FromStream(stream);
stream.Dispose();
}
// delete your file.
File.Delete(delpath);
var uploadedFile = Request.Files[0]; //Get file
var fileName = Path.GetFileName(uploadedFile.FileName); //get file name
string fileSavePath = Server.MapPath(fileName); //get path
uploadedFile.SaveAs(fileSavePath); //saving file
FileInfo info = new FileInfo(fileSavePath);//get info file
//the problem ocurred because this,
FileStream s = new FileStream(fileSavePath, FileMode.Open); //openning stream, them file in use by a process
System.IO.File.Delete(fileSavePath); //Generete a error
//problem solved here...
s.Close();
s.Dispose();
System.IO.File.Delete(fileSavePath); //File deletad sucessfully!
I had the similar issue. The only difference was that I was using Binding(MVVM Pattern). Nothing much worked then I removed everything and tried with Binding Mode=OneWay along with GC.Collect() before calling File.Delete(path) and it worked finally.
I had the same issue. The problem I had was with the openFileDialog and saveFileDialog having the following set:
MyDialog.AutoUpgradeEnabled = false;
I commented out that line and it was resolved.
In my case, I started a new process of devenv.exe opening a temporary solution file. After the process was ended, I found I could not delete the directory for few minutes. Checking with "resmon", resource monitor, I found it was a executable called PerfWatson2.exe that was using the temp file. Looking at the site, PerfWatson is actually a Visual Studio Customer Experience Improvement Program from MicroSoft. It will lock the file or directory you temporarily used even after you have ended the VS IDE.
The solution is to disable the Visual Studio Customer Experience Improvement Program, see this. This shoudln't be an issue after your app is publihsed. But it is quite annoying during debuging.
I have been trying to load my image in bitmap image class. But whenever I am trying to save an image (using a third party library called Image Processor) the quality drops. So my question is that:
Is there any way i can save image in its full quality?
src.BeginInit();
src.UriSource = new Uri("picture.jpg", UriKind.Relative);
src.CacheOption = BitmapCacheOption.OnLoad;
src.EndInit();
You can achieve image saving without any thirdparty libraries. But you should know, that saving JPEG always drops quality a bit - its a nature of that format, not an issue with library. Using the JpegBitmapEncoder you can configure the quality, and with the maximum value you will not see a picture degradation, but anyway it present. So, consider using of PNG format instead.
Here is a short snippet how to load and save a JPEG image:
// Load from file or any other source.
var uri = new Uri(#"D:\InputImage.jpg");
var bitmap = new BitmapImage(uri);
// Save to file.
var encoder = new JpegBitmapEncoder(); // Or any other, e.g. PngBitmapEncoder for PNG.
encoder.Frames.Add(BitmapFrame.Create(bitmap));
encoder.QualityLevel = 100; // Set quality level 1-100.
using (var stream = new FileStream(#"D:\OutputImage.jpg", FileMode.Create))
{
encoder.Save(stream);
}
WebImage works very well and I use often this class in my application. It has a lot of nice built-in features, for example, saving proportins when resizing an image:
WebImage wi = new WebImage(imageName);
wi.Resize(314, 235, true);
wi.Save(imageName, "png");
I am trying to save and load an ImageSource (or BitmapSource) to and from an XML file. A quick look on SO gave me this answer.
It looked ok so I tried it out but I am getting a strange result.
When I try this code everything works:
BitmapSource testImgSrc = new WriteableBitmap(new BitmapImage(new Uri("pack://application:,,,/MyNameSpace;component/Images/MyImg.png")));
BackgroundImage = testImgSrc;
But when I try this code the image just does not appear at all:
BitmapSource testImgSrc = new WriteableBitmap(new BitmapImage(new Uri("pack://application:,,,/MyNameSpace;component/Images/MyImg.png")));
string testImgStr = ImageToBase64(testImgSrc);
BitmapSource testImg = Base64ToImage(testImgStr);
BackgroundImage = testImg;
There don't seem to be any errors or exceptions. When steping through the code BackgroundImage looks like it gets set to a valid image object.
My WPF form has an image control that has it's source bound to a property that returns the result of the BackgroundImage property. I am guessing the binding is working ok because the first test works as expected.
Can anyone help me to understand why the second test is not displaying my image?
There's a problem with Base64ToImage method from this answer. The documentation states that with the default OnDemand cache option the stream must not be closed before the image is actually used. In your case this means that the Image element is trying to access the already disposed stream.
The fix is pretty simple, you just need to change the cache option to OnLoad and the problem is gone:
BitmapSource Base64ToImage(string base64)
{
byte[] bytes = Convert.FromBase64String(base64);
using (var stream = new MemoryStream(bytes))
{
return BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
This seems like a fairly simple issue, but I can't seem to figure a way to work around it.
In a WPF window I have an image, image_small_pic. In the associated C# file I set the value of that using this code:
Uri src = new Uri(image_source, UriKind.RelativeOrAbsolute);
small_image_bmp = new BitmapImage(src);
image_small_pic.Source = small_image_bmp;
Where small_image_bmp is a public BitmapImage object. But then if then, later on, if I change small_image_bmp to another file and reassign image_small_pic.Source, then the original image is still locked and I can't delete it. Even if I try later it's still locked. Any thoughts how I can free this up?
Check out this article. There's some odd behaviour with WPF images that you're coming across. The solution is to read in the bytes yourself and then create an image based on them, since if you let the framework handle it, the file will remain locked.
Uri src = new Uri(image_source, UriKind.RelativeOrAbsolute);
var small_image_bmp = new BitmapImage();
small_image_bmp.BeginInit();
small_image_bmp.CacheOption = BitmapCacheOption.OnLoad;
small_image_bmp.UriSource = src;
small_image_bmp.EndInit();
image_small_pic.Source = small_image_bmp;