Loading image from picture library to image source - c#

I am capturing an image . Project places the image in picture library that is C:\...\Pictures\PreviewFrame.jpg.
I have an image tag
<Image Name="ClinicImage"></Image>
Now i want to load that PreviewFrame.jpg in this tag.
I tried this
ClinicImage.Source=new BitmapImage(new Uri(path));
where
path is a string variable containing image path.
But it is not getting loaded. How should i do it?
Thanks in advance.

There is some retrictions about what the universal applications can access.
You need first to be sure that the picture library capability is properly added in your application manifest.
Then, you can open the image using GetFileFromPathAsync() and provide the stream to the BitmapSource using SetSourceAsync()
var file = await StorageFile.GetFileFromPathAsync("c:\\users\\me\\images\\a.png");
var stream = await file.OpenReadAsync();
var imageSource = new BitmapImage();
await imageSource.SetSourceAsync(stream);

Make sure your slashes are set correctly. If I remember correctly, you need to work with double backslash instead of single.

Related

c# WPF URI syntax

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

Save PDF to file

I am working on a Windows Store app for Windows 8.1, and I can't find anything that addresses what I need to do. I am trying to save an image of a pdf page to my local app data storage. I have the following:
private async void GetFirstPage()
{
// Retrieve file from FutureAccessList
StorageFile file = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFileAsync(token);
// Truncate last 4 chars; ex: '.pdf'
FileName = file.Name.Substring(0, file.Name.Length - 4);
// Get access to pdf functionality from file
PdfDocument doc = await PdfDocument.LoadFromFileAsync(file);
// Get a copy of the first page
PdfPage page = doc.GetPage(0);
// Below could be used to tweak render options for optimizations later
//PdfPageRenderOptions options = new PdfPageRenderOptions();
// Render the first page to the BitmapImage
InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
await page.RenderToStreamAsync(stream);
// Common code
Cover.SetSource(stream);
// Convert the active BitmapImage Cover to a storage file to be stored locally
// ???
}
The variable, Cover, is a BitmapImage that is bound in XAML to display the image to the user. I want to save this image to my local app data so that I don't have to re-render it through the PDF library every time my app opens! The problem is I can't save anything in a Windows Store app from a stream unless it is text to my knowledge, (no filestream or fileoutputstreams for me), and Cover's URI source is null, since it was sourced from a stream, making it difficult to get my BitmapImage, Cover, to a StorageFile for proper Windows Store saving.
Everything works for me currently, I'm just upset about re-rendering the pdf page to my bitmapimage from scratch every time my app opens. Thanks in advance for any input!
You need to save the image from the PdfPage directly rather than from the BitmapImage since you can't get the data out of the BitmapImage. The PdfPage.RenderToStreamAsync already encodes the stream as a bitmap so you don't need to do any manipulation beyond sending it to the file. This is essentially the same as what you are doing to save to the InMemoryRandomAccessStream, except to a file based stream:
//We need a StorageFile to save into.
StorageFile saveFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("safedPdf.png",CreationCollisionOption.GenerateUniqueName);
using (var saveStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
{
await page.RenderToStreamAsync(saveStream);
}

C# - WPF how to unreference a BitmapImage so I can delete the source file?

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;

Does WriteableBitmap has new features in Silverlight 4?

and if someone could give me an example on how to use it, with a stream? (not sure how that works) I know how to create a BitmapImage from an URI now I need to convert this image to a WriteableBitmap, but I get a null exception error with something like this:
BitmapImage image = new BitmapImage(new Uri("http://www.example.com/example.png"));
WriteableBitmap newImage = new WriteableBitmap(image);
In short: Nope, there are no new features in Silverlight 4. The WriteableBitmapEx tries to compensate the missing functionality.
Regarding your real problem:
You should add a handler to the BitmapImage.ImageFailed event to see if there's an error when the image should be downloaded. And you you should create the WriteableBitmap in the ImageOpened event handler.
var image = new BitmapImage(new Uri("http://www.example.com/example.png"));
WriteableBitmap newImage = null;
image.ImageOpened += (s, e) => newImage = new WriteableBitmap(image);
Please also note that cross-domain references are permitted. See the MSDN page for details. You should put the image into the Web Project's ClientBin folder and use a relative path instead.
As an alternative you can also compile the image into the assembly as resource and load it from there. The WriteableBitmapEx has an extension method to make this task a bit easier. But keep in mind that this blows the assembly size up and the initial XAP loading time will increase.
// Load an image from the calling Assembly's resources only by passing the relative path
var writeableBmp = new WriteableBitmap(0, 0).FromResource("example.png");

convert bitmap to image c# [duplicate]

this is how my code look now:
System.Drawing.Image objImage = System.Drawing.Image.FromFile(Server.MapPath("aaa.jpg"));
int height = objImage.Height;
int width = objImage.Width;
System.Drawing.Bitmap bitmapimage = new System.Drawing.Bitmap(objImage, width, height);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmapimage);
System.Drawing.Image bitmap2 = (System.Drawing.Image)Bitmap.FromFile(Server.MapPath("sem.png"));
g.DrawImage(bitmap2, (objImage.Width - bitmap2.Width) / 2, (objImage.Height - bitmap2.Height) / 2);
MemoryStream stream = new MemoryStream();
bitmapimage.Save(stream, ImageFormat.Jpeg);
String saveImagePath = Server.MapPath("ImagesMerge/") + "aaa.jpg";
bitmapimage.Save(saveImagePath);
imgBig.ImageUrl = saveImagePath;
The problem I have now is that the image is not displayed in browser, I don't understand why .
like jmaglasang said, I would suggest to you to use an ashx file and if you don't need to keep the image, just send the image stream directly to the http without saving it on the disk
so you only need to do something like
<img src="Handler.ashx?action=merge&image1=blah.jpg&image2=bloh.jpg">
look at this code for an example of how to send an image made in memory that does not exist on the drive
Bitmap is a subclass of Image, so there no need to convert Bitmap to Image. It already is...
Probably because saveImagePath will be a local path (such as c:\somepath\aaa.jpg) that is not reachable from the browser. You probably want to set the ImageUrl = "ImagesMerge/aaa.jpg" instead.
You can also try:
imgBig.ImageUrl = ResolveUrl(saveImagePath);
EDIT:
If saveImagePath is under the WebApplication Directory, doing some modifications on the directory structure i.e. modifying files, deleting and creating can cause the application pool to recycle, and once it reaches the maximum recycle count the application pool will be stopped causing "Server unavailable" error.
I would suggests to add/save/modify images on a separate directory (not under the Apps Directory) then create a Handler(ASHX) that will read the images, just an advice though.
MapPath will give you a physycal address, not a virtual address which is what the browser needs to get to the image.
You might be forgetting to set the Response.Headers. Check out the following example that shows how to create bar chart images and then display it on the screen:
http://www.highoncoding.com/Articles/399_Creating_Bar_Chart_Using__NET_Graphics_API.aspx

Categories