How to add PNG and JPG at runtime - c#

I am using C# and WPF. I want to add a PNG and JPG at runtıme to an image source but I get an exception that says:
Can not implicitly add convert type string to Sytem.Windows.Media.imageSource
using System.IO; //for : input - output
using Microsoft.Win32; //For : OpenFileDialog / SaveFileDialog
using System.Windows.Media.Imaging; //For : BitmapImage etc etc
<Image x:Name="img" Margin="9,13.5,6,0.5" Source="Laugh.ico">
private void ac(object sender, RoutedEventArgs args)
{
OpenFileDialog dlg = new OpenFileDialog();
// Configure open file dialog box
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".PNG"; // Default file extension
dlg.Filter = " (.PNG)|*.PNG"; // Filter files by extension
// Show open file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process open file dialog box results
if (result == true)
{
// Open document
string filename = dlg.FileName;
img.Source=filename;
}
}

Sorry but as you might have noticed, that code wonT even compile. You cannot set the image source as the filename
img.Source = filename
Have a look at the reference.
Try this:
img.Source = new BitmapImage(new Uri(filename));

Not sure if this will work for an image outside of the program, but you can try:
Uri uri = new Uri(dlg.File.FullName, UriKind.RelativeOrAbsolute);
ImageSource imgSource = new BitmapImage(uri);
img.Source = imgSource;

I think the key line is:
img.Source=filename
which should be something like:
BitmapImage bi= new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(filename, UriKind.Relative);
bi.EndInit();
img.Source = bi;
As you have to actually read the image file in from disk.

Related

Close a file which is in use from a PictureBox

I'm using this code for converting Excel to image and preview it in a picturebox.
The code is working for first time. But when i'm trying to upload second time i get an error that says that the image file is in use.specically in save point.
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "bak files (*.xls)|*.xls|All files (*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
Img1 = openFileDialog1.FileName;
//Create a new Workbook object and
//Open a template Excel file.
Workbook book = new Workbook(Img1);
//Get the first worksheet.
Worksheet sheet = book.Worksheets[0];
//Define ImageOrPrintOptions
ImageOrPrintOptions imgOptions = new ImageOrPrintOptions();
//Specify the image format
imgOptions.ImageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
//Only one page for the whole sheet would be rendered
imgOptions.OnePagePerSheet = true;
//Render the sheet with respect to specified image/print options
SheetRender sr = new SheetRender(sheet, imgOptions);
//Render the image for the sheet
Bitmap bitmap = sr.ToImage(0);
//Save the image file specifying its image format.
bitmap.Save("C:\\1.jpg");\\in this point i get my error that it says general error GDI+.
pictureBox2.Image = Image.FromFile("C:\\1.jpg");
pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
}
else
{
this.DialogResult = DialogResult.None;
}
}
I thing i must stop first use from my picturebox preview and then to upload again. But how will i do that? I tried
pictureBox1.Image=null
,but it didnt worked.
When you use
pictureBox2.Image = Image.FromFile("C:\\1.jpg");
The static call keeps the file open (and locked). So you can't overwrite the file.
Solution:
if (pictureBox2.Image != null) pictureBox2.Image.Dispose();
bitmap.Save("C:\\1.jpg");
bitmap.Dispose();
pictureBox2.Image = new Bitmap(Image.FromFile("C:\\1.jpg"));
This way the file is released and can later be overwritten.
An alternative:
if (pictureBox2.Image != null) pictureBox2.Image.Dispose();
bitmap.Save("C:\\1.jpg");
bitmap.Dispose();
using (Bitmap bm = new Bitmap(C:\\1.jpg"))
{
pictureBox2.Image = new Bitmap(bm);
};
I solved this using FileStream.
Dim fs1 As System.IO.FileStream
fs1 = New System.IO.FileStream(Bitmap, IO.FileMode.Open, IO.FileAccess.Read)
PictureBox1.Image = System.Drawing.Image.FromStream(fs1)
fs1.Close()
Look that you should fs1.close() to finish the stream.
The FileStream Class represents a File in the machine. FileStream allows to move data to and from the stream as arrays of bytes. It means, it does'nt works directly in the file, just as a Stream that you can manipulate.
The code is in vb.net (because it works for me).
So there will be no problem translating it to C #
Here VB.NET Example for opening Image in picture box without keeping file locked for other operation.
VB.NET Code.
Dim fs As System.IO.FileStream
' Specify a valid picture file path on your computer.
fs = New System.IO.FileStream("C:\WINNT\Web\Wallpaper\Fly Away.jpg",
IO.FileMode.Open, IO.FileAccess.Read)
PictureBox1.Image = System.Drawing.Image.FromStream(fs)
fs.Close()
C# Code.
System.IO.FileStream fs;
// Specify a valid picture file path on your computer.
fs = new System.IO.FileStream(#"C:\WINNT\Web\Wallpaper\Fly Away.jpg", System.IO.FileMode.Open, System.IO.FileAccess.Read);
PictureBox1.Image = System.Drawing.Image.FromStream(fs);
fs.Close();
Reference -
https://www.codeproject.com/Questions/492654/5bc-23-5dplusdeleteplusimagepluswhichplusisplusope

Can't overwrite a file wrapped in a using statement

I'm building an app that is supposed to do the following :
User selects an element in a listbox (example : frog)
A picture corresponding to the element is opened as the background on a canvas, on which the user can draw
When the user selects another element of the listbox, the canvas is saved as a picture named after the unchecked element, with "New" added (example : frogNew)
This new element is added to the listbox, and if the user edits it again, it is saved under the same name (example : frogNew)
Things are working out, except the part where I try to save a canvas under the same name (frogNew). I get an error saying that I cannot save the file as it is already open. Can you tell me where if don't close the file properly in my code ?
private void save_picture(string name)
{
//This part takes a screenshot of the canvas, named "paintSurface"
RenderTargetBitmap rtb = new RenderTargetBitmap((int)paintSurface.RenderSize.Width, (int)paintSurface.RenderSize.Height, 96d, 96d, System.Windows.Media.PixelFormats.Default);
rtb.Render(paintSurface);
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
//If the file already exists, we add "New" to its name
var regex1 = new Regex(#"New$");
if (regex1.Match(nom).ToString() == "")
{
using (var fs = System.IO.File.OpenWrite(#"D:\Test" + name + "New.png"))
{
pngEncoder.Save(fs);
}
}
else
{
using (var fs = System.IO.File.OpenWrite(#"D:\Test" + name + ".png"))
{
pngEncoder.Save(fs);
}
}
}
private void listBox1_SelectedIndexChanged(object sender, SelectionChangedEventArgs e)
{
//When the index of listbox changes, I save the canvas in a file named after the former index
List<string> oldItemNames = new List<string>();
if (e.RemovedItems.Count != 0)
{
var oldPhoto = e.RemovedItems[0].ToString();
save_picture(oldPicture);
}
//I start a new canvas with the picture corresponding to the new index as a background
paintSurface.Children.Clear();
ImageBrush newBrush = new ImageBrush();
newBrush.ImageSource = new BitmapImage(new Uri(#"D:\Test" + listBox1.SelectedItem.ToString() + ".png", UriKind.Relative));
paintSurface.Background = newBrush;
}
Any idea why this line "using (var fs = System.IO.File.OpenWrite(#"D:\Test" + name + ".png"))" always gives me the error that this file is already open ? How can I close it?
This is because your file is locked by the BitmapImage that you're using as the image source
You need to specify the BitmapCacheOption.OnLoad option while initializing the bitmap image:
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.UriSource = new Uri(#"D:\Test" + listBox1.SelectedItem.ToString() + ".png", UriKind.Relative);
bitmapImage.EndInit();
newBrush.ImageSource = bitmapImage;
I don't think it's your save operation keeping the file open. It's the read operation near the end of your code sample. You open FooNew.png, edit it, and try to write to the same file.
Try this. Where you have:
newBrush.ImageSource = new BitmapImage(new Uri(#"D:\Test" + listBox1.SelectedItem.ToString() + ".png", UriKind.Relative));
Replace with:
using (FileStream fileStream = File.OpenRead(#"D:\Test" + listBox1.SelectedItem.ToString() + ".png"))
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = fileStream;
bitmapImage.EndInit();
newBrush.ImageSource = bitmapImage;
}
Once you get this working, you're going to realize that File.OpenWrite() isn't what you want in save_picture. It would append the new PNG to any existing file contents. You want File.Create() which creates a new file or overwrites an existing one.

how to set picturebox image location from zip without extrat?

I want to set picture box from zip file without extract zip.
my code:
ZipFile zip = new ZipFile("data.zip");
using (Stream s = zip["p3.png"].OpenReader())
{
picturebox.ImageLocation = s.ToString();
}
Picture Box Show error image.
I should use Bitmap. Correct Code:
ZipFile zip = new ZipFile("data.zip");
using (Stream s = zip["p3.png"].OpenReader())
{
Bitmap bitmap= new Bitmap(s);
PictureBox picturebox.Image = bitmap;
}

LockScreen for windows phone 8

Hi I am developing a lockscreen app where I am using listbox of images.After selecting a image when i am clicking a button to set lockscreen,It should updated.But it bot updating .Here is my code
private async void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
MediaLibrary mediaLibrary = new MediaLibrary();
//ImageSource im = image1.Source;
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(mediaLibrary.Pictures[imageList.SelectedIndex].GetImage());
String tempJPEG = "MyWallpaper1.jpg";
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempJPEG))
{
myIsolatedStorage.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(tempJPEG);
StreamResourceInfo sri = null;
Uri uri = new Uri(tempJPEG, UriKind.Relative);
sri = Application.GetResourceStream(uri);
WriteableBitmap wb = new WriteableBitmap(bitmap);
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 90);
fileStream.Close();
}
LockScreenChange(tempJPEG);
}
private async void LockScreenChange(string filePathOfTheImage)
{
if (!LockScreenManager.IsProvidedByCurrentApplication)
{
await LockScreenManager.RequestAccessAsync();
}
if (LockScreenManager.IsProvidedByCurrentApplication)
{
var schema = "ms-appdata:///Local/";
var uri = new Uri(schema + filePathOfTheImage, UriKind.Absolute);
LockScreen.SetImageUri(uri);
var currentImage = LockScreen.GetImageUri();
MessageBox.Show("Success", "LockScreen changed", MessageBoxButton.OK);
}
else
{
MessageBox.Show("Background cant be changed. Please check your permissions to this application.");
}
}
Actually when first time the app is launched and when I am clicking set button,the current selected image is set as lockscreen,after that when i am selecting another image,it is showing lockscreen changed ,success.No error and no exception.I dont know where is the problem.
Please help........
It got solved by changing temporary file name to original file name i.e. string tempJpeg

C# - The process cannot access the file because it is being used by another process

public static void CopyImage(Image picToSave, string name)
{
if (picToSave.Source != null)
{
BitmapImage src = (BitmapImage)picToSave.Source;
if (!Directory.Exists("Images"))
{
Directory.CreateDirectory("Images");
}
FileStream stream = new FileStream("Images/" + name + ".jpg", FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(src));
encoder.Save(stream);
stream.Close();
}
}
The problem occurs when i choose a file which already exists in the /Images directory, i guess it just cant overwrite, The exception is thrown at the "FileStream"" line (FileMode.Create I guess).
If i Choose a file which isn't in the /Images directory it works fine and copies the file to the Images Directory like it should..
Thank you :)
How did you load the image in the first place? If you didn't change the default value for CacheOption, the file is locked by the BitmapImage object. You need to specify BitmapCacheOption.OnLoad:
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = imageUri;
image.CacheOption = BitmapCacheOption.OnLoad;
image.EndInit();
Assuming you created Bitmaps from all the images in the image folder this sounds like a known problem with the Bitmap class - it keeps a file lock on the file you created it from until you call dispose. Also see this thread: .NET app locks file.
Hans Passant offers the following workaround in this thread: Loading a file to a Bitmap but leaving the original file intact
public static Image LoadImageNoLock(string path) {
using (var ms = new MemoryStream(File.ReadAllBytes(path))) {
return Image.FromStream(ms);
}
}
Just thought I would post something that worked for me from #Thomas Levesque's comment.
FileStream stream = new FileStream(imageLocation, FileMode.Open);
Image image = new Image();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = stream;
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.EndInit();
image.Source = bi;
image.Height = 15;
btn.Content = image;
stream.Close();
stream.Dispose();
try with some modifications in your code
set the write permission to your opened file
FileStream stream = new FileStream("Images/" + name + ".jpg", FileMode.Create, FileAccess.Write);

Categories

Resources