How to add watermark to all files in folder? - c#

I am use method, in which openfiledialog and savefiledialog for second method for add watermark on one picture, press button-call method
How to realize this for all pictures in folder?
I think,neccesary used folderbrowserdialog like this:
AddWatermarkOnAllPictures_Click ()
{
folderbrowser.Dialog.ShowDialog();
{
}
}
I am right? May be, i must call method, which adds watermark and this methods work with ALL pictures in folder?

Assuming "folderbrowser" is your FolderBrowserDialog
Iterate over the selected directory:
if (folderbrowser.ShowDialog() != DialogResult.OK) return;
foreach(string file in System.IO.Directory.GetFiles(folderbrowser.SelectedPath))
{
// Do something
}

Related

Disposing of image when using PictureBox

I'm working with a Winforms program that was written a while ago. I've come across some issues with it and I'm trying to optimize the way it handles some things but I'm running across some issues with disposing.
Below is what is currently implementing.
First, It starts with going through the files in the Pictures folder and copies them into a preview folder.
foreach (string s in files)
{
fileName = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(path, fileName);
File.Copy(s, destFile, true);
}
Next, it opens a form via ShowDialog:
frmPreview frm = new frmPreview(FileNameArray, lblParcel.Text);
frm.ShowDialog();
Next, it goes to the Preview form and gets to this code:
try {
FlowLayoutPanel imagePanel = new FlowLayoutPanel();
if (System.IO.Directory.Exists(path))
{
folder = new DirectoryInfo(path);
foreach (FileInfo files in folder.GetFiles())
{
System.Diagnostics.Debug.Print(files.Extension);
if ((string.Equals(files.Extension, ".jpg", StringComparison.OrdinalIgnoreCase)) || (string.Equals(files.Extension, ".gif", StringComparison.OrdinalIgnoreCase)) || (string.Equals(files.Extension, ".png", StringComparison.OrdinalIgnoreCase)))
{
PictureBox image = new PictureBox();
image.Image = Image.FromFile(files.FullName);
image.SizeMode = PictureBoxSizeMode.Zoom;
image.Size = this.Size;
imagePanel.Controls.Add(image);
}
}
}
this.Controls.Add(imagePanel);
System.Threading.Thread.Sleep(0);
return;
}
catch
{
}
The code above basically takes all the photos, creates a PictureBox with each one, and adds the PictureBox to the FlowLayoutPanel to display in a window for previewing. Problem with this is that it does not dispose properly and gets caught up after trying to visit this preview window for the 3rd time (closing the window and opening it a second time works fine but creates a second process).
Lastly, It implements the following when the form closes.
private void frmPreview_FormClosed(object sender, FormClosedEventArgs e)
{
this.Dispose();
this.Close();
}
The error happens on the 3rd time the preview window is called, when the program goes through the foreach statement posted at the top.
The full line where it catches is:
File.Copy(s, destFile, true);
The process cannot access the file 'C:\Users\username\Pictures\Preview\image.jpg' because it is being used by another process.
I'm 99.9% sure it's because of the PictureBox and FlowLayoutPanel but I can't figure out what to do to fix it. I'd like to change as little as possible since this isn't my program and it will soon be rewritten completely. I mainly just need to temporarily fix the issue until we finish the big picture where this whole program will get scrapped.
I've found a couple posts that seem to be similar issues but none of the fixes have changed anything at all. Below are all the posts I looked into and trying implementing unsuccessfully:
file-copy-the-process-cannot-access-the-file
file-is-being-used-by-another-process
dispose-of-a-picturebox
Issue fixed after implementing the recommendation of #RezaAghaei. Changed the Preview form to this:
foreach (FileInfo files in folder.GetFiles())
{
System.Diagnostics.Debug.Print(files.Extension);
if ((string.Equals(files.Extension, ".jpg", StringComparison.OrdinalIgnoreCase)) || (string.Equals(files.Extension, ".gif", StringComparison.OrdinalIgnoreCase)) || (string.Equals(files.Extension, ".png", StringComparison.OrdinalIgnoreCase)))
{
using (var stream = new FileStream(files.FullName, FileMode.Open))
{
PictureBox image = new PictureBox();
image.Image = Image.FromStream(stream);
image.SizeMode = PictureBoxSizeMode.Zoom;
image.Size = this.Size;
imagePanel.Controls.Add(image);
}
}
}
I also improved the efficiency of the ShowDialog call by implementing a using block:
using (frmPreviewPhotos frm = new frmPreviewPhotos(NEWphotoFileNameArray, lblParcel.Text))
{
frm.ShowDialog();
}

Restricting access to certain folders with a FolderBrowserDialog

I want to restrict what folder a person can choose to set their default save path in my app. Is there a class or method which would allow me to check access rights and either limit the user's options or show an error once they have made their selection. Is FileSystemSecurity.AccessRightType a possibility?
Since the FolderBrowserDialog is a rather closed control (it opens a modal dialog, does it stuff, and lets you know what the user picked), I don't think you're going to have much luck intercepting what the user can select or see. You could always make your own custom control, of course ;)
As for testing if they have access to a folder
private void OnHandlingSomeEvent(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if(result == DialogResult.OK)
{
String folderPath = folderBrowserDialog1.SelectedPath;
if (UserHasAccess(folderPath))
{
// yay! you'd obviously do something for the else part here too...
}
}
}
private bool UserHasAccess(String folderPath)
{
try
{
// Attempt to get a list of security permissions from the folder.
// This will raise an exception if the path is read only or do not have access to view the permissions.
System.Security.AccessControl.DirectorySecurity ds =
System.IO.Directory.GetAccessControl(folderPath);
return true;
}
catch (UnauthorizedAccessException)
{
return false;
}
}
I should note that the UserHasAccess function stuff was obtained from this other StackOverflow question.

C# Windows Forms: OpenFileDialog Strange Issues

This is kinda strange, let me try to explain it as best as possible:
When I create a new file and Save it, it saves correctly (test.xml).
When I make changes to this file and Save it, it saves correctly (to test.xml)
When I make changes again to this file or just choose Save As, it works correctly (newtest.xml)
However, when I do a file open, make changes to a file (test.xml) and click Save it is saving to (newtest.xml).
This is in my MainForm.cs
if (this.openEditorDialog1.ShowDialog(this) == DialogResult.OK && editForm != null)
{
editForm.Close();
editForm = new EditorForm(this);
editForm.OpenFile(this.openEditorDialog1.FileName);
editForm.Closing += new CancelEventHandler(EditorForm_Closing);
editForm.MdiParent = this;
editForm.Show();
}
private void biFileSave_Click(object sender, EventArgs e)
{
if (!editForm.HasFileName)
{
if (this.saveEditorDialog1.ShowDialog(this) == DialogResult.OK)
{
this.ActiveDiagram.SaveSoap(this.saveEditorDialog1.FileName);
editForm.FileName = this.saveEditorDialog1.FileName;
}
}
else
{
this.ActiveDiagram.SaveSoap(this.saveEditorDialog1.FileName);
}
This is in my EditorForm.cs
public void OpenFile(string strFileName)
{
diagramComponent.LoadSoap(mainForm.openEditorDialog1.FileName);
this.FileName = mainForm.openEditorDialog1.FileName;
this.tabControl1.SelectedTab = DiagramTab;
}
I'm sure it has to do with the what I'm doing in the EditoForm but I can't seem to figure it out.
else
{
this.ActiveDiagram.SaveSoap(this.saveEditorDialog1.FileName);
It looks like you want:
this.ActiveDiagram.SaveSoap(editForm.FileName);
It must have to do with mainForm.openEditorDialog1.FileName. Use a FileName property of the form that does the saving. When you open the file, set the fileName to mainForm.openEditorDialog1.FileName. When you SaveAs, set the FileName property there, too. This way, whenever the current file, changes you set the FileName property appropriately. Then, when it comes time to save the file, you always have the correct filename.
In summary, only use the .FileName property of the SaveAs dialog or the FileOpen dialog right after you use them.

Open a .txt file into a richTextBox in C#

I want to be able to open a .txt file up into a richtextbox in c# and also into a global variable i have made called 'notes' but don't know how to do this. This is the code i have at the moment:
OpenFileDialog opentext = new OpenFileDialog();
if (opentext.ShowDialog() == DialogResult.OK)
{
richTextBox1.Text = opentext.FileName;
Globals.notes = opentext.FileName;
}
Only problem is it doesn't appear in neither the richtextbox nor in the global varibale, and the global allows it to be viewed in another richtextbox in another form. So please can you help, with ideally the .txt file going into both,
Thanks
Do you mean you want to have the text displayed or the filename?
richTextBox1.Text = File.ReadAllText(opentext.FileName);
Globals.notes = richTextBox1.Text;
You probably also want to correct this to:
if (opentext.ShowDialog() == DialogResult.OK)
In c# there are not global variables. The closest thing you can get is to make the variable "public static". But a better solution would be to make it an instance variable of an object you have access to, for example your main window class.
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
System.IO.StreamReader sr = new System.IO.StreamReader(openFileDialog1.FileName);
richTextBox1.Text = sr.ReadToEnd();
sr.Close();
}
FileName property of OpenFileDialog control just gives the full path of file selected by user. In order to read the content of this file, you will need to use a method like File.ReadAllText.
Try using this, I used it for a chat program and it works fine, you can set your timer rate to whatever you want. You also don't have to use a timer, you can have a button initiate the refresh of the rich text box.
private void refreshRate_Tick(object sender, EventArgs e)
{
richTextBox1.Text = File.ReadAllText(#"path.txt");
}
Hope this helps!
I hope, I am not late. It seems like there is something like:
OpenFileDialog opentext = new OpenFileDialog();
if (opentext.ShowDialog() == DialogResult.OK)
{
string selectedFileName = opentext.FileName;
richTextbox.LoadFile(selectedFileName, RichTextBoxStreamType.UnicodePlainText);
}
Refs

Recursive directory listing using WinForms TreeView?

I want to make a treeview that shows all folders on the system, and only shows music files, such as .mp3 .aiff .wav etc.
I remember reading that I need to use a recursive function or something along those lines.
Usually most computers have thousands of folders and hundreds of thousands of files, so displaying all of them in a TreeView recursively with be very slow and consume a lot of memory, view my answer in this question, citing my answer with some modifications when can get a pretty usable GUI:
// Handle the BeforeExpand event
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
if (e.Node.Tag != null) {
AddDirectoriesAndMusicFiles(e.Node, (string)e.Node.Tag);
}
}
private void AddDirectoriesAndMusicFiles(TreeNode node, string path)
{
node.Nodes.Clear(); // clear dummy node if exists
try {
DirectoryInfo currentDir = new DirectoryInfo(path);
DirectoryInfo[] subdirs = currentDir.GetDirectories();
foreach (DirectoryInfo subdir in subdirs) {
TreeNode child = new TreeNode(subdir.Name);
child.Tag = subdir.FullName; // save full path in tag
// TODO: Use some image for the node to show its a music file
child.Nodes.Add(new TreeNode()); // add dummy node to allow expansion
node.Nodes.Add(child);
}
List<FileInfo> files = new List<FileInfo>();
files.AddRange(currentDir.GetFiles("*.mp3"));
files.AddRange(currentDir.GetFiles("*.aiff"));
files.AddRange(currentDir.GetFiles("*.wav")); // etc
foreach (FileInfo file in files) {
TreeNode child = new TreeNode(file.Name);
// TODO: Use some image for the node to show its a music file
child.Tag = file; // save full path for later use
node.Nodes.Add(child);
}
} catch { // try to handle use each exception separately
} finally {
node.Tag = null; // clear tag
}
}
private void MainForm_Load(object sender, EventArgs e)
{
foreach (DriveInfo d in DriveInfo.GetDrives()) {
TreeNode root = new TreeNode(d.Name);
root.Tag = d.Name; // for later reference
// TODO: Use Drive image for node
root.Nodes.Add(new TreeNode()); // add dummy node to allow expansion
treeView1.Nodes.Add(root);
}
}
Recursively searching all drives for particular files is not going to work well. It will take about a minute to do so with today's large drives.
One standard trick, used by Windows Explorer, is to only list the top level directories and files. It puts a dummy node in a directory node. When the user opens the node (BeforeExpand event), it searches only that directory and replaces the dummy node with the directories and files found it that directory. Again putting a dummy node in the directories. Etcetera.
You can see this at work by adding an empty subdirectory. The directory node will be shown with the + glyph. When you open it, Explorer discovers that there are no directory or files to be listed and deletes the dummy node. The + glyph disappears.
This is very fast, listing the content of a single directory takes well less than a second. There's a problem however using this approach in your case. The odds that a directory contains a suitable music file are small. The user will constantly be frustrated by finding out that the navigating through a set of subdirectories produces nothing.
That's why Windows has a dedicated place to store specific media files. My Music in this case. Use Environment.GetFolderPath(Environment.SpecialFolder.MyMusic) to find it. Iterating it should not take long.

Categories

Resources