I am binding to 5 different images in my program and wish to leave the capability of the user to replace or update the photos under the same name. So when updating these pictures, the binding will be notified and change while the program is running.
The program is a Digital VMB (visual management board) at my workplace, so it needs to remain running and have these photos be updated on the server without a hitch. Currently I am binding to a property in my C# which is a string containing the image location.
In c#:
public string OpenFilePathProp { get; set; }
In XAML:
<Image x:Name="OpenWOImage" Source="{Binding OpenFilePathProp}" Stretch="Fill" Margin="25,0,25,0"/>
When the user goes to copy and replace the image with the newer one, they can't as it's "currently open in another process". Which I suppose is the data binding in my WPF.
Can this be overcome by opening the images into a filestream and then binding to the stream? If so, I'm completely unsure on how to bind to a filestream; I'm quite new to WPF AND C#.
Thanks for the help. I HAVE tried to look for a solution to this, but I think I'm just getting confused and I don't think it will resolve my problem since it seems the binding is what's "keeping the image open" and I'm not sure how to bind to an Image object AND close that object to allow for overwriting
EDIT: Thought I should mention that I've managed to copy the images in question to the AppData folder for my VMB program,
like,
string AppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\";
System.IO.File.Copy(Properties.Settings.Default.OpenWOFilePath, System.IO.Path.Combine(AppData, "ROAMaintenanceVMB\\OpenWOFilePath_Copy.jpeg"), true);
this way I can "check" every so often to see that someone has overwritten the photos on the server, and THEORETICALLY copy the "new" photos to the AppData folder, overwriting the previous versions. THIS is where the issue of the images already being open in another program arises.
Following Peter Duniho suggestion about using WriteableBitmap worked in my instance.
string imagePath = "";
Uri imageUri = new Uri(imagePath);
BitmapImage bitmapImage = new BitmapImage(imageUri);
ImageProperty = new WriteableBitmap(bitmapImage);
<Image Source="{Binding ImageProperty}"/>
What's going on here is:
BitmapImage is created from the given path
WriteableBitmap is created based on the BitmapImage (a "deep copy"?)
The important thing here is the original image is not locked, as the binding is tied to the copy of the image of WriteableBitmap - not to the image itself, so the image can be deleted / replaced freely.
Related
I understand that this question has been asked (and answered) before. However, none of the solutions are working for me.
Below is a screen capture of all the relevant pieces of the puzzle:
Screen capture http://dinosaur-island.com/PlantPictureBoxScreenCap.jpg
As you can see there are numerous bitmaps of plants loaded as resources into the Images folder. There is a form with a picturebox named "PlantPicture". There is string, which I know has a good path (because I've checked it in the debugger):
PicPath = PicPath+".bmp";
Screen capture http://dinosaur-island.com/PlantDebugger.jpg
I've tried numerous ways of loading, casting, etc., etc.
The path should be something like: "Images\a.bmp". (Note the lack of a leading slash, and the slashes being back slashes.)
And then:
pictureBox1.Image = Image.FromFile(#"Images\a.bmp");
I just tried it to make sure, and it works. This is besides the other answer that you got - to "copy always".
Ok...so first you need to import the image into your project.
1) Select the PictureBox in the Form Design View
2) Open PictureBox Tasks
(it's the little arrow printed to right on the edge of the PictureBox)
3) Click on "Choose image..."
4) Select the second option "Project resource file:"
(this option will create a folder called "Resources" which you can access with Properties.Resources)
5) Click on "Import..." and select your image from your computer
(now a copy of the image will be saved in "Resources" folder created at step 4)
6) Click on "OK"
Now the image is in your project and you can use it with the Properties command. Just type this code when you want to change the picture in the PictureBox:
pictureBox1.Image = Properties.Resources.MyImage;
Note:
MyImage represent the name of the image...
After typing "Properties.Resources.", all imported image files are displayed...
It depends on your file path. For me, the current directory was [project]\bin\Debug, so I had to move to the parent folder twice.
Image image = Image.FromFile(#"..\..\Pictures\"+text+".png");
this.pictureBox1.Image = image;
To find your current directory, you can make a dummy label called label2 and write this:
this.label2.Text = System.IO.Directory.GetCurrentDirectory();
The accepted answer has major drawback!
If you loaded your image that way your PictureBox will lock the image,so if you try to do any future operations on that image,you will get error message image used in another application!
This article show solution in VB
and This is C# implementation
FileStream fs = new System.IO.FileStream(#"Images\a.bmp", FileMode.Open, FileAccess.Read);
pictureBox1.Image = Image.FromStream(fs);
fs.Close();
Setting "Copy to Output Directory" to "Copy always" or "Copy if newer" may help for you.
Your PicPath is a relative path that is converted into an absolute path at some time while loading the image.
Most probably you will see that there are no images on the specified location if you use Path.GetFullPath(PicPath) in Debug.
I have a game application in Visual Studio 2012 C#. I have all the .png images I am using in the Resources file of the project.
Have you any idea why I can access all the files but one by using Properties.Resources?
I checked the full filePath and it's set to the resources folder. And it's added in the program as I did Add -> Existing Item and added the image.
It looks just like the other images. I have no idea why it's not loading. I need this since I need to send a .exe by email to my lecturer and without this image the project is nothing!
I added this in the resource file
internal static System.Drawing.Bitmap grid_fw {
get
{
object obj = ResourceManager.GetObject("grid.fw", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
and although now grid is available, it is returning null :/
Found from: Properties.Resources the icon name does not appear in the intellisense
You also need to add the icon to the Resources.resx file. Open it in
Visual Studio and drag your icon into the Icons menu of the resx and
it will become available.
Also, see Adding and Editing Resources (Visual C#)
You can get a reference to the image the following way:
Image myImage = Resources.yourImage;
If you want to make a copy of the image, you'll need to do the following:
Bitmap bmp = new Bitmap(Resources.yourImage);
Don't forget to dispose of bmp when you're done with it. If you don't know the name of the resource image at compile-time, you can use a resource manager:
ResourceManager rm = Resources.ResourceManager;
Bitmap yourImage = (Bitmap)rm.GetObject("yourImage");
The benefit of the ResourceManager is that you can use it where Resources.myImage would normally be out of scope, or where you want to dynamically access resources. Additionally, this works for sounds, config files, etc.
The application is a desktop document management system. Image files (of scanned docs) are stored within a shared network folder and its indices within a database. Now, when the image of a selected document page is displayed the user has the option to delete it (via a contextual menu). The problem is, if I try to do this then it throws an exception (the resource is locked) which has all the sense given that it's being shown on screen. So, currently I maintain a persistent delete queue. Once the app starts I go to the queue and delete the pages of the documents whose indices were deleted from DB and given that they aren't being displayed the deletion succeed but this seems to be pretty bad code (I mean it works, but not as clean as it should, I guess).
How bad my quick solution is. Given that the app is single-user then the user needs to star the app to use it. Is this a very bad idea or can I implemented using another path.
The images are shown (within the document viewer) by binding it to the current file:
View:
<Image Name="PageViewedPath" Margin="20" Grid.Column="0" />
ViewModel:
public string PageViewedPath { get; set; }
And once the user clicks next or previous I change (within the ViewModel the PageViewedPath). Maybe the problem is this binding which I can't control in detail, I'm using Caliburn Micro so that's why just by setting the image name the binding is done.
I think maybe overriding this binding and creating a hardcopy of the image before is being shown must work but I'm not sure if it will and worse, how to do it.
I've had a similar problem in an application I developed that was using an image pool. Although the image was not displayed anymore, the file was locked and could not be deleted.
I solved my problem by loading images with BitmapCacheOption.OnLoad, something like this:
Image myImage = new Image();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.UriSource = imageUri;
// End initialization.
bi.EndInit();
myImage.Source = bi;
Here's a link to an msdn post that shows how to use BitmapCacheOption from xaml:
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/3cb97997-941f-42a8-a03b-f84b152c1139/
If you code lock the files from your own code - stop locking. You probably missing some using/Dispose calls somewhere around loading an image.
If it is not your code or you need to handle failures due to using shared files location - your solution may be ok. Also most users will not expect such behavior - my normal expectation is that file is either deleted instantaneously or never.
For a project I'm working I would like the user (admin) to be able to change the picture on the page he is currently on. I managed to upload the image to "the server" using interlink. This basicly uploads it to a given folder on a server, in my case being: Interlink/Uploads.
But now I don't really know how can I tell my website to replace the source of the image that is currently shown with the source of the uploaded image.
Another something I would like to do is create a simple image gallery with all the images in that folder, once again I don't know how to do this.
I hope somebody can help me, Thanks.
Thomas
Edit: Just so clarify, the application is written in silverlight (XAML, C#). I apologise for any inconvenience.
I take it that the "Silverlight" portion of this question is related only to Interlink (your file uploader), and not to the page itself, which I presume is straight HTML.
If that's the case, you've got several options for changing the local image. The simplest way is simply to wait until you know that your file upload has finished (presumably Interlink has some way of notifying you that this is the case), and then run something like this bit of JavaScript:
<script type='text/javascript'>
function changeImage(newImageSource) {
document.getElementById('myTargetImage').setAttribute('src', newImageSource);
}
</script>
As far as displaying a simple image gallery with all the images in the folder, my recommendation would be to look into one of the numerous jquery plugins that handle this sort of thing, e.g.:
http://www.1stwebdesigner.com/css/fresh-jquery-image-gallery-display-solutions/
EDIT: Silverlight Options
You basically have the same options, except you're doing them in C# instead of JavaScript. For instance, when Interlink tells you that the new image has been uploaded, run this:
string imageName = "something.jpeg";
var ub = new UriBuilder(HtmlPage.Document.DocumentUri);
ub.Path = "/Interlink/Uploads/" + imageName;
img.Source = new BitmapImage(ub.Uri);
And for an image carousel, something like this:
http://3dimagecarousel.codeplex.com/
You'll just need to provide the URL's of all the images. The easiest way to do that is probably to expose a web service method that lists them all.
Hi there
I am working with visual web developer and would a) like to know how I could programatcally add a picture to the website, instead of going to Website and then add existing item. The idea I have is to upload the picture using the file upload control but then I want to have it added so that it can be accessed using a gridview.
b)I would also like to know how to size the picture using C# code obviously so that is displayed at the correct size.
best regards
arian
here is a full project with source code to manipulate images, including resize.
http://www.codeproject.com/KB/web-image/ASPImaging1.aspx
And a sample code only for resize
http://weblogs.asp.net/gunnarpeipman/archive/2009/04/02/resizing-images-without-loss-of-quality.aspx
You can use GetThumbnailImage to easily create a smaller verson of the uploaded image. The code looks something like (it's free typed without a compiler, so there may be some errors):
System.Drawing.Image pic = new System.Drawing.Bitmap(sourceFilename);
System.Drawing.Image thumb = pic.GetThumbnailImage(targetXSize,targetYSize,
new System.Drawing.Image.GetThumbnailImageAbort(this.GetThumbnailImageAbort),
IntPtr.Zero);
thumb.Save(thumbPathName);
I believe the Image implements IDisposable, so you need to remember to Dispose of them when you're done.
The abort parameter can be a function that simply does this (can't remember off the top of my head when it gets called):
bool GetThumbnailImageAbort() {
return false;
}