How to save an image to a file in WPF - c#

I am new in wpf control and framework. I cant seem to save my images can you help me
Below is my code
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = System.IO.Path.GetFileNameWithoutExtension(newlist[currentPicture]);
Nullable<bool> result = sfd.ShowDialog();
if (result == true)
{
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(newlist[currentPicture]);
bmp.Save(newlist[currentPicture]);
}

For a System.Drawing.Bitmap, you need to pass the dialog's FileName property to the Save method.
EDIT: In WPF:
var encoder = new PngBitmapEncoder()
encoder.Frames.Add(BitmapFrame.Create(image));
using (var stream = dialog.OpenFile())
encoder.Save(stream);

Related

PictureBox Not Releasing Resources

My application is used to store scanned images, with additional information, to an SQL Database. Because I use a picturebox to accomplish this there is an issue I've become aware of with the picturebox holding open resources. This is preventing me from doing anything with the original file until I close my form. I have tried various ways to dispose of the picturebox with no success. Need help with the following code to release the resources held by the picturebox.
using (OpenFileDialog GetPhoto = new OpenFileDialog())
{
GetPhoto.Filter = "images | *.jpg";
if (GetPhoto.ShowDialog() == DialogResult.OK)
{
pbPhoto.Image = Image.FromFile(GetPhoto.FileName);
txtPath.Text = GetPhoto.FileName;
txtTitle.Text = System.IO.Path.GetFileNameWithoutExtension(GetPhoto.Fi‌​leName);
((MainPage)MdiParent).tsStatus.Text = txtPath.Text;
//GetPhoto.Dispose(); Tried this
//GetPhoto.Reset(); Tried this
//GC.Collect(): Tried this
}
}
Saving the image to my database uses the following:
MemoryStream stream = new MemoryStream();
pbPhoto.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] pic = stream.ToArray();
It's usually FromFile() that causes locking issues: (not the PictureBox itself)
The file remains locked until the Image is disposed.
Change:
pbPhoto.Image = Image.FromFile(GetPhoto.FileName);
To:
using (FileStream fs = new FileStream(GetPhoto.FileName, FileMode.Open))
{
if (pbPhoto.Image != null)
{
Image tmp = pbPhoto.Image;
pbPhoto.Image = null;
tmp.Dispose();
}
using (Image img = Image.FromStream(fs))
{
Bitmap bmp = new Bitmap(img);
pbPhoto.Image = bmp;
}
}
This should make a copy of the image for use in the PictureBox and release the file itself from any locks.

How to add an existing item via code in wpf

I am attempting to copy a selected image to a folder and then want to display it with an Image object. The copying works fine, but when I want to display it it seems like the program cannot find it. Displaying the image only works if I manually use "add existing Item". Is there a way to add it automatically?
Here is my code:
string name = "image1";
OpenFileDialog dialog = new OpenFileDialog();
Nullable<bool> dialogOK = dialog.ShowDialog();
if(dialogOK == true)
{
File.Copy(dialog.FileName, #"..\..\Images\" + name + ".png", true);
image.Source = new BitmapImage(new Uri(#"Images\" + name + ".png", UriKind.Relative));
}
("image" is defined in xaml)
It seems safer to use an absolute path for loading the BitmapImage:
var dialog = new OpenFileDialog();
if (dialog.ShowDialog() == true)
{
var targetFile = #"..\..\Images\" + name + ".png";
var currentDir = Environment.CurrentDirectory;
var targetPath = Path.Combine(currentDir, targetFile);
var targetDir = Path.GetDirectoryName(targetPath);
Directory.CreateDirectory(targetDir);
File.Copy(dialog.FileName, targetPath, true);
image.Source = new BitmapImage(new Uri(targetPath));
}
In order to release the file directly after loading the BitmapImage, load it from a FileStream:
BitmapImage bitmap = new BitmapImage();
using (var stream = File.OpenRead(targetPath))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}
image.Source = bitmap;

how to make Image save as a 24-bit image?

How do I get C# to force bitmap images that are saved to be saved as 24-bit images as can be seen when you get the right-click properties of the image in Windows. All the images I save are set to 32-bit. I tried the below code with no luck. The source images are all 24-bit as well but are always saved as 32-bit image
public void Save(int index)
{
string savestrFilename;
SaveFileDialog dialog = new SaveFileDialog();
dialog.Title = "image save...";
dialog.OverwritePrompt = true;
dialog.Filter = "JPEG File(*.jpg)|*.jpg|Bitmap File(*.bmp)|*.bmp";
if (dialog.ShowDialog() == DialogResult.OK)
{
savestrFilename = dialog.FileName;
System.IO.FileStream stream = new System.IO.FileStream(savestrFilename , System.IO.FileMode.Create);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.QualityLevel = 70;
encoder.Frames.Add(BitmapFrame.Create(_grabImageList[index].BitmapImage));
encoder.Save(stream);
stream.Close();
}
}

after selecting image display same image inside picturebox

on buttonclick I'm taking image from file system and save into database, everything is ok but I want when I select image to display that image into pictureBox1
OpenFileDialog open = new OpenFileDialog() { Filter = "Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.png;*.jpg" };
if (open.ShowDialog() == DialogResult.OK)
{
txtPhoto.Text = open.FileName;
}
string image = txtPhoto.Text;
Bitmap bmp = new Bitmap(image);
FileStream fs = new FileStream(image, FileMode.Open, FileAccess.Read);
byte[] bimage = new byte[fs.Length];
fs.Read(bimage, 0, Convert.ToInt32(fs.Length));
fs.Close();
byte[] Photo = bimage;
You can use Image property to set the Image for PictureBox Control.
Try This:
DialogResult result= openFileDialog1.ShowDialog();
if(result==DialogResult.OK)
pictureBox1.Image =new Bitmap(openFileDialog1.FileName);
if you want to add it in your code
Complete Code:
OpenFileDialog open = new OpenFileDialog() { Filter = "Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.png;*.jpg" };
if (open.ShowDialog() == DialogResult.OK)
{
txtPhoto.Text = open.FileName;
}
string image = txtPhoto.Text;
Bitmap bmp = new Bitmap(image);
pictureBox1.Image = bmp;//add this line
FileStream fs = new FileStream(image, FileMode.Open, FileAccess.Read);
byte[] bimage = new byte[fs.Length];
fs.Read(bimage, 0, Convert.ToInt32(fs.Length));
fs.Close();
byte[] Photo = bimage;
Simple code:
picturebox.Image = Bitmap.FromFile(yourimagepath);
OpenFileDialog open = new OpenFileDialog()
{
Filter = "Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.png;*.jpg"
};
if (open.ShowDialog() == DialogResult.OK)
{
PictureBoxObjectName.Image = Image.FromFile(open.FileName);
}
openFileDialog1.Multiselect = false;
openFileDialog1.Filter= "jpg files (*.jpg)|*.jpg";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
foreach (String file in openFileDialog1.FileNames)
{
picturebox1.Image = Image.FromFile(File);
}
}
This is for selection of one image.

How to save BitmapImage via SaveFileDialog from WPF?

The way I try implement it via standart Windows.Forms (to get valide DialogResult.OK)
System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
// dlg.DefaultExt = ".jpg"; // Default file extension
dlg.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif";
if(dlg.ShowDialog()== System.Windows.Forms.DialogResult.OK)
if (dlg.DialogResult.HasValue && splashDialog.DialogResult.Value)
{
string fName = dlg.FileName;
if (dlg.FileName != "")
{
System.IO.Stream fileStream = (System.IO.FileStream)dlg.OpenFile();
fileStream.Close();
}
}
This is using Windows forms but it saves blank image((
You can do something like that:
var encoder = new JpegBitmapEncoder(); // Or PngBitmapEncoder, or whichever encoder you want
encoder.Frames.Add(BitmapFrame.Create(yourImage));
using (var stream = dlg.OpenFile())
{
encoder.Save(stream);
}
BTW, there is a SaveFileDialog in WPF too, you don't have to use the one from Windows Forms
For WPF code will be like :
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document";
dlg.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif";
if (dlg.ShowDialog() == true)
{
var encoder = new JpegBitmapEncoder(); // Or PngBitmapEncoder, or whichever encoder you want
encoder.Frames.Add(BitmapFrame.Create(bi));
using (var stream = dlg.OpenFile())
{
encoder.Save(stream);
}
}
Here bi is the BitmapImage

Categories