Show image from picture box? - c#

I have project with C#. I add picture box control to show images are coming from the database.
I have a DbComand that executes "select * from Client "; and a DataReader to read the results:
byte[] buffer = (byte[])dr[24];
if (buffer != null)
{
groupBox1.Visible = true;
MemoryStream ms = new MemoryStream(buffer);
pictureBox1.Image = Image.FromStream(ms);
}
How I can open Windows Photo Viewer with the image that display in the picture box...

You can open it with below Code:
Process.Start(#"C:\Picture.jpg");

You can save the image form the Picturebox to a temporary file and show that by running the PhotoViewer dll. That can be done with the rundll32 helper by using the Process class. Your code would look like this:
// get a tempfilename and store the image
var tempFileName = Path.GetTempFileName();
pictureBox1.Image.Save(tempFileName, ImageFormat.Png);
string path = Environment.GetFolderPath(
Environment.SpecialFolder.ProgramFiles);
// create our startup process and argument
var psi = new ProcessStartInfo(
"rundll32.exe",
String.Format(
"\"{0}{1}\", ImageView_Fullscreen {2}",
Environment.Is64BitOperatingSystem?
path.Replace(" (x86)",""):
path
,
#"\Windows Photo Viewer\PhotoViewer.dll",
tempFileName)
);
psi.UseShellExecute = false;
var viewer = Process.Start(psi);
// cleanup when done...
viewer.EnableRaisingEvents = true;
viewer.Exited += (o, args) =>
{
File.Delete(tempFileName);
};
See this answer for how the Photoviewer can be started from the commandline.

If you are working in a forum application you can add a picturebox with the toolbox, if u did that go to your properties of the picturebox and press the three dots next to the name image in your properties by doing that. Press local resource and you are in your own documents. hope this helped you

Related

IOException when trying to delete an image

I have a profile page where the user can change their profile picture, When the user clicks submit their old profile picture is delete and replace with a the new one. However, when I try and delete the image it gives the error below:
IOException: The process cannot access the file
'C:\Users\Shayan\source\repos\RestaurantWeb\RestaurantWeb\wwwroot\Images\Users\92487709-5b2f-417c-a64f-4661962693cf_imb5ohqzqr511.jpg'
because it is being used by another process.
Here is my snippet of code where I add and delete the images:
if (accountDetailsViewModel.ProfilePicture != null)
{
string fileName = FileUploadHelper.GetUniqueFileName(accountDetailsViewModel.ProfilePicture.FileName);
string filePath = FileUploadHelper.GetProfileFilePath(fileName, _webHostEnvironment);
await accountDetailsViewModel.ProfilePicture.CopyToAsync(new FileStream(filePath, FileMode.Create));
user.ProfileImagePath = fileName;
string previousImageFilePath = FileUploadHelper.GetProfileFilePath(accountDetailsViewModel.PreviousPicturePath, _webHostEnvironment);
if (System.IO.File.Exists(previousImageFilePath) && accountDetailsViewModel.PreviousPicturePath != "noprofilepic.jpeg")
{
System.IO.File.Delete(previousImageFilePath);
}
}
Why is this happening? Am I meant to be closing the file? I'm not using File.Create() so I can't really close it like:
var img = File.Create(filePath);
img.Close();
Try closing the FileStream that you're creating.
Edit: Check out this.

Hash files are different after taking same screen shot with Selenium

I'm trying to learn about automated tests, using Selenium. I'm working alone, and so only have the docs, Google and then you guys.
Using Selenium in VS-2105, I save a screen shot of my website as an image to a file location, and then stop debugging at that point. This file then becomes the 'expected' result.
I then comment that line out, run it again, taking a screen shot but saving to a different location. The files, although of the same size, have different hash values.
To my eyes they are identical.
Is there something wrong with my approach?
This is the code which I run to create my 'master'
_webDriver.Navigate().GoToUrl(url);
var accept = _webDriver.SwitchTo().Alert();
accept.Accept();
IWebElement menu = _webDriver.FindElement(By.Id("link"));
menu.Click();
System.Threading.Thread.Sleep(500);
var screenshot = _webDriver.GetScreenshot();
var fileName = "expandMenuInPlan.png";
var origFile = _testImagesPersistentPath + fileName;
screenshot.SaveAsFile(origFile, OpenQA.Selenium.ScreenshotImageFormat.Png);
And this is the code I use to compare
_webDriver.Navigate().GoToUrl(url);
var accept = _webDriver.SwitchTo().Alert();
accept.Accept();
IWebElement menu = _webDriver.FindElement(By.Id("link"));
menu.Click();
System.Threading.Thread.Sleep(500);
var screenshot = _webDriver.GetScreenshot();
var fileName = "expandMenuInPlan.png";
var origFile = _testImagesPersistentPath + fileName;
//screenshot.SaveAsFile(origFile, OpenQA.Selenium.ScreenshotImageFormat.Png); COMMENTED OUT
//The above is identical
var newFile = _testImagesTempForTestRunPath + fileName;
screenshot.SaveAsFile(newFile, OpenQA.Selenium.ScreenshotImageFormat.Png);
string hashOrig = GetBytes(origFile);
string hashNew = GetBytes(newFile);
if (hashOrig != hashNew)
{
SaveFailedImage(origFile, newFile, fileName);
}
And the GetBytes method
private string GetBytes(string file)
{
using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
var img = new Bitmap(file);
ImageConverter converter = new ImageConverter();
var bytes = (byte[])converter.ConvertTo(img, typeof(byte[]));
return Convert.ToBase64String(sha1.ComputeHash(bytes));
}
}
Is using screenshots in this manner just not reliable or is there something wrong with my code?
Hashing a image file and comparing is never the right approach. Even a single pixel off will change the hash. So you don't want to to make your tests brittle
You can use the C# method ImageComparer.Compare Method (Image, Image, ColorDifference, Image)
https://msdn.microsoft.com/en-in/library/hh191601.aspx?f=255&MSPPError=-2147217396
Or you can use external tools like https://applitools.com/ which allow you to do compare images which are smart in nature
PS: I have no association with applitools and it is just one example, there might be other services available as well.

process cannot access the image file because it is being used by another process

i downloaded images from my deployed website and save it into my WPF app folder , basically i am running 2 platforms , a website and WPF . What i am trying to do is users uploaded their images using the web , so on the WPF side , i download the image from the web and display on my WPF app but i got this error :
The process cannot access the file
'C:\Users\apr13mpsipa\Desktop\OneOrganizer\OneOrganizer\bin\Debug\TaskImage\Fill
in the blanks.jpg' because it is being used by another process.
This is the code :
protected void DownloadData(string strFileUrlToDownload, string taskName)
{
WebClient client = new WebClient();
byte[] myDataBuffer = client.DownloadData(strFileUrlToDownload);
MemoryStream storeStream = new MemoryStream();
storeStream.SetLength(myDataBuffer.Length);
storeStream.Write(myDataBuffer, 0, (int)storeStream.Length);
storeStream.Flush();
currentpath = System.IO.Directory.GetCurrentDirectory() + #"\TaskImage\" + taskName + ".jpg"; //folder to contain files.
using (FileStream file = new FileStream(currentpath, FileMode.Create, System.IO.FileAccess.ReadWrite)) // ERROR HERE
{
byte[] bytes = new byte[storeStream.Length];
storeStream.Read(bytes, 0, (int)storeStream.Length);
file.Write(myDataBuffer, 0, (int)storeStream.Length);
storeStream.Close();
}
//The below Getstring method to get data in raw format and manipulate it as per requirement
string download = Encoding.ASCII.GetString(myDataBuffer);
}
I got the error when i try to display a image on a first button click , then i display the image again on the other button . basically this happens when i try to display the image 2 times.
---EDIT ------
Updated as of baldrick's comment :
DownloadData(fileUploadDirectory + daoTask.GetImage(aid, actTask.taskID).Substring(1), daoTask.GetTaskName(aid, actTask.taskID));
Image imgActivityTask = new Image();
imgActivityTask.Height = 90;
imgActivityTask.Width = 90;
imgActivityTask.Margin = new Thickness(10);
BitmapImage img = new BitmapImage();
img.BeginInit();
img.UriSource = new Uri(currentpath, UriKind.Absolute);
img.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
img.EndInit();
imgActivityTask.Source = img;
Its still giving me the same error on the using line.
In you WPF code, you might need to specify the IgnoreImageCache setting:
yourImage.CacheOption = BitmapCacheOption.OnLoad;
yourImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache
This might force it to load, and not lock the file.
The answer here deals with the same problem.
I am guessing you are leaving the file stream open.
Not sure why you are creating a memory stream (by the way, don't forget to close memory stream), and a file stream when you already have the bytes? Why not directly write to the file using File.WriteAllBytes?
WebClient client = new WebClient();
byte[] myDataBuffer = client.DownloadData(strFileUrlToDownload);
currentpath = System.IO.Directory.GetCurrentDirectory() + #"\TaskImage\" + taskName + ".jpg"; //folder to contain files.
File.WriteAllBytes(currentPath, myDataBuffer);
//The below Getstring method to get data in raw format and manipulate it as per requirement
string download = Encoding.ASCII.GetString(myDataBuffer);
Not sure why you are creating a memory stream (by the way, don't forget to close memory stream), and a file stream when you already have the bytes? Why not directly write to the file using File.WriteAllBytes?
WebClient client = new WebClient();
byte[] myDataBuffer = client.DownloadData(strFileUrlToDownload);
currentpath = System.IO.Directory.GetCurrentDirectory() + #"\TaskImage\" + taskName + ".jpg"; //folder to contain files.
File.WriteAllBytes(currentPath, myDataBuffer);
//The below Getstring method to get data in raw format and manipulate it as per requirement
string download = Encoding.ASCII.GetString(myDataBuffer);
Thanks

The process cannot access the file ' ' because it is being used by another process

I am trying to delete local copy(on the computer) of an image file once uploaded using file dialog. It throws The process cannot access the file 'C:\Documents and Settings\username\My Documents\My Pictures\1220.bmp' because it is being used by another process.
private void _btnImportPhoto_Click(object sender, RoutedEventArgs e)
{
//user clicked import/change photo, open file dialog to browse for photo
System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog();
fileDialog.Multiselect = false;
fileDialog.Filter = ResourceFile.PhotoFileTypes;
if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
FilePath = fileDialog.FileName;
FilePathCopy = fileDialog.FileName;
string safeFilePath = fileDialog.SafeFileName;
Bitmap bitmap = new Bitmap(FilePath);
CurrentPhoto = bitmap;
Bitmap bitmap1 = new Bitmap(FilePathCopy); //A copy to save when if delete local copy is chosen
m_PhotoCopy = bitmap1;
FileSystem.DeleteFile(FilePath);
}
_btnSave.IsEnabled = _btnCancel.IsEnabled = true;
}
}
Please let me know how to work around this issue.
Thanks.
you need to dispose of the bitmap object try doing this. As this will dispose of the bitmap object as soon as it leaves the using context { }
using (Bitmap bitmap1 = new Bitmap(FilePathCopy))
{
//do all bitmap stuff in here
}
First I see
Bitmap bitmap = new Bitmap(FilePath);
CurrentPhoto = bitmap;
Where CurrentPhoto I presume some global variable that you want hold.
This, instead throws and exception:
FileSystem.DeleteFile(FilePath);
Cause image file at FilePath is actually CurrentPhoto. What you can do.
1) If use of CurrentPhoto has any sense inside this function, do what you want to do inside this function, and after dispose CurrentPhoto object, even in a way like #Bobby suggests (using block)
2) If you want to have it by the way, you can try to use Bitmap's Clone
method like this:
CurrentPhoto = bitmap.Clone();
and after call your:
bitmap.Dispose();
FileSystem.DeleteFile(FilePath);
Should work.
Try this...
http://www.lockergnome.com/blade/2006/11/28/windows-error-message-error-deleting-file-or-folder/
It will allow you to delete files or folder.

Open image in Windows Photo Viewer

How to open .jpg image in Windows Photo Viewer from C# app?
Not inside app like this code,
FileStream stream = new FileStream("test.png", FileMode.Open, FileAccess.Read);
pictureBox1.Image = Image.FromStream(stream);
stream.Close();
I think you can just use:
Process.Start(#"C:\MyPicture.jpg");
And this will use the standard file viewer associated with .jpg files - by default the windows picture viewer.
Start it in a new Process
Process photoViewer = new Process();
photoViewer.StartInfo.FileName = #"The photo viewer file path";
photoViewer.StartInfo.Arguments = #"Your image file path";
photoViewer.Start();
The code fetch photo from ftp and shows the photo in Windows Photo Viewer.
I hope it will usefully for you.
public void ShowPhoto(String uri, String username, String password)
{
WebClient ftpClient = new WebClient();
ftpClient.Credentials = new NetworkCredential(username,password);
byte[] imageByte = ftpClient.DownloadData(uri);
var tempFileName = Path.GetTempFileName();
System.IO.File.WriteAllBytes(tempFileName, imageByte);
string path = Environment.GetFolderPath(
Environment.SpecialFolder.ProgramFiles);
// create our startup process and argument
var psi = new ProcessStartInfo(
"rundll32.exe",
String.Format(
"\"{0}{1}\", ImageView_Fullscreen {2}",
Environment.Is64BitOperatingSystem ?
path.Replace(" (x86)", "") :
path
,
#"\Windows Photo Viewer\PhotoViewer.dll",
tempFileName)
);
psi.UseShellExecute = false;
var viewer = Process.Start(psi);
// cleanup when done...
viewer.EnableRaisingEvents = true;
viewer.Exited += (o, args) =>
{
File.Delete(tempFileName);
};
}
Best Regards...
public void ImageViewer(string path)
{
Process.Start("explorer.exe",path);
}
Path is the file path of the image to be previewed.
I am trying the other answers but they all return the same error about how the location isn't an OS App, so I'm not sure where the issue lies. I did however discover another method to open the file.
string Location_ToOpen = #"The full path to the file including the file name";
if (!File.Exists(Location_ToOpen))
{
return;
}
string argument = "/open, \"" + Location_ToOpen + "\"";
System.Diagnostics.Process.Start("explorer.exe", argument);
It starts out by testing if the file exists or not. If it doesn't exist it would have caused an error.
After that it simulates a "open" request on a file explorer without opening a file explorer, then the system opens the file with the default app.
I am currently using this method in my project so I hope it works for you too.

Categories