Save Bitmap to disk and release saved file Rendered from DevDept Eyeshot - c#

In a WPF application, I need to save a Bitmap to disk and than after some changes I try to delete the saved file and save again the modified image.
The problem is once saved, the bitmap doesn't release the file and throws an exception when I try to delete it.
//Gets a bitmap from DevDept.EyeShot model via Scene.RenderToBitmap() and save it to disk
using (var bmpRight = Scene.RenderToBitmap(new System.Drawing.Size(100, 100)))
{
bmpRight.Save(rightPath.Replace(".stl", ".jpg"));
}
Than the user modifies the 3D model and tries to save again with the same name. (Because it is associated to an appointment).
When I try to delete it
if (System.IO.File.Exists(rightPath.Replace(".stl", ".jpg")))
System.IO.File.Delete(rightPath.Replace(".stl", ".jpg"));
I throws an error :
The process cannot access the file because it is in use by another process.
If I do the same thing without Scene2.RenderToBitmap() method of the 3D plateforme, it doesn't produce any error. But, how can it be ? There is no relation between the physical file and the plateforme!
Any idea pleae ?

Related

How do I load an image at run time?

Hello guys I've tried to call an image at run time in XNA but it gives me an error "file not found" I've given the full path but it keeps returning a error. All I want is load a single image at some point the image does not exist when the game is executed (hard to explain). So I wanted to load this image generated by the game process is it possible?
if (File.Exists(FILE))//Checks if the file exist
ImageTexture = this.Content.Load<Texture2D>(#"C:\FullPath");
A: What is "C:\FullPath"? It's nothing. I very much doubt you have a file there.
B: XNA requires you load a local file if you're going to use Content.Load - it must be in the GamePath/Content folder. EG: GamePath/Content/MySprite.xnb
C: If you want to load a random image, you must use Texture2D.FromStream, like so:
System.IO.FileStream mystream = new System.IO.FileStream("C:/MyFile.png", System.IO.FileAccess.Read);
Image = Texture2D.FromStream(GraphicsDevice, mystream);
mystream.Dispose();

UnauthorizedAccessException when trying to save a photo to the same file a second time

So, the code below allows me to take a picture. I then display the picture. My XAML is bound to the Photo property of the Vehicle object. It works fine, until I go in and try to take a picture again. I then get an UnauthorizedAccessException. I create the file in 'LocalStorage', so I don't believe I need special permissions to write files there. I'm not sure what is causing the error.
public async Task TakePicture()
{
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(16, 9);
StorageFile photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
var targetFolder = ApplicationData.Current.LocalFolder;
var targetFile = await targetFolder.CreateFileAsync(String.Format
("VehiclePhoto{0}.jpg", this.Vehicle.PrimaryKey), CreationCollisionOption.ReplaceExisting);
if (targetFile != null)
{
await photo.MoveAndReplaceAsync(targetFile);
this.Vehicle.Photo = String.Format("ms-appdata:///local/VehiclePhoto{0}.jpg", this.Vehicle.PrimaryKey);
}
}
}
I assume that StoragePhoto encapsulates some kind of File I/O under the hood. You must properly dispose these objects in order to release the underlying unmanaged OS resources that will keep "hooks" into the file. If you don't dispose them, the application will keep access to the file open, which is probably why your second access to the file gives you an exception (the first access still remains). Show me the StoragePhoto code and I can get more specific.
On another note, if this application is multi-threaded, you should create granular semaphores/locks around writing the files to disk (perhaps by interning the physical path string and locking on that reference) to ensure you don't try to write the same file to disk at the same physical path at the same time - that would be bad.

"Saving" directly to Clipboard - Possible?

I'm working with an API that produces images in BMP or JPG format. The API method in question requires a path and filename. However, in some cases, I would like to simply put the image into the Clipboard.
I know I can save to a file, then open the file and copy the Stream's data to the Clipboard:
private void SaveSnapshot(string path)
{
var pathWasblank = path.IsNullOrBlank();
path = path.NullIfBlank() ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),"tempFile.jpg");
myApiInstance.ExportJPG(path, 100, true);
//to ensure the file has made it to the filesystem
while(!File.Exists(path)) Thread.Sleep(100);
if (pathWasblank) //it should be on the Clipboard and not in a file
{
using (var stream = File.OpenRead(path))
Clipboard.SetImage(Image.FromStream(stream));
File.Delete(path); //cleanup;
}
}
What I want to know is if there is a way to skip having to reopen, copy and then delete the file, and instead "save" directly to the Clipboard by specifying some file path that corresponds to the Clipboard. If not, no big deal; I have a working solution.

c# ASP.NET How do i delete a file that is "in use" by another process?

I'm loading a file:
System.Drawing.Image img = System.Drawing.Image.FromFile(FilePath);
Now I would like to save the image:
img.Save(SavePath);
This works.. Unless FilePath == SavePath, then it decides to give me the error:
System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.
So I tried to delete the file, right after opening it:
System.Drawing.Image img = System.Drawing.Image.FromFile(FilePath);
File.Delete(FilePath);
And it gives me the error:
System.IO.IOException: The process cannot access the file 'filename.jpg' because it is being used by another process.
So...
How can I modify an existing file, that's "in use" when its not in use by anyone?
The image will remain locked until it is disposed (See here).
The file remains locked until the Image is disposed.
You'll have to save the image somewhere else (or copy its contents out) and then dispose the opened image via using a using clause.
Example:
using(Image image1 = Image.FromFile("c:\\test.jpg"))
{
image1.Save("c:\\test2.jpg");
}
System.IO.File.Delete("c:\\test.jpg");
System.IO.File.Move("c:\\test2.jpg", "c:\\test.jpg");
you can either use Memory stream or put it in byte[] array
http://www.vcskicks.com/image-to-byte.php

Overwriting an image file (bitmap)

Hello I am trying to save a bitmap image in a basic image editor program.
Here's the code:
// then save it
ImageBoxInApp.Image.Save(filename);
[EDIT] And I am opening the image with this
openFileDialog1.Title = "Select an Image";
openFileDialog1.Filter = "All Files|*.*|Windows Bitmaps|*.bmp|JPEG Files|*.jpg";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
filename = openFileDialog1.FileName;
Image img = System.Drawing.Image.FromFile(filename);
So when I try this I receive a Generic GDI+ error. So I found a solution to this and it looks like this:
// Delete existing file first
System.IO.File.Delete(filename);
// then save it
ImageBoxInApp.Image.Save(filename);
But when I try to do this I receive another error saying that the file I am deleting is currently open. This is because that is the file that I am trying to edit.
How do I "close" the file without actually closing the application? Or is there an alternative solution?
Thanks!
Its hard to say without seeing some context around how your loading the file, but here are a couple of suggestions:
Before saving, copy the existing image into a new Image, close the original, perform the delete, and save the copy.
Save the file to a random filename, delete the original, rename the randomly named file to the original name.
Load the file into a memory stream and use the in memory copy to initialize the image.
I'd personally go with option #3 for most cases. Be sure to dispose of the image when you've finished using it - it is best if you can wrap it in a using ( ) block.

Categories

Resources