I am trying to load in a bunch of images from my resource file but I am getting the FileNotFoundException for some reason. the Image names are like so:
"image01.png", "image02.png", ... , "image10.png", image11.png"
In the end I want to be able to display all of the images on the screen.
Here is what I have:
String imgName;
int row = 0, col = 0;
for (int i = 1; i <= 15; i++)
{
//get the name of the current image
if (i < 10)
imgName = "image0" + i + ".png";
else
imgName = "image" + i + ".png";
Image img = null;
try {
img = Image.FromFile(imgName);//read the image from the resource file
}
catch (Exception e) { Console.WriteLine("ERROR!!!" + e); }
}
Here is a sample error output that I am getting:
ERROR!!!System.IO.FileNotFoundException: tile01.png
at System.Drawing.Image.FromFile(String filename, Boolean useEmbeddedColorManagement)
at System.Drawing.Image.FromFile(String filename)
Screenshot:
I have also fixed a type on line 56 from: "PictureForm.PuzzleForm." to "PicturePuzzle." but still no luck.
You are not specifying a path to load the file from. They will be loaded from where the assembly is running.
Note that Image.FromFile does not load an embedded resource, but rather the .png from disk. I assume this is what you intend.
Check the properties for the images in Visual Studio and ensure that Copy to Output Directory is Copy if Newer or Copy Always. Here's a screenshot (in my case it's a cursor resource, but same idea for an image).
UPDATE
If you have embedded your images in your EXE or another file, you can use code similar to
System.Reflection.Assembly thisExe;
thisExe = System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream file =
thisExe.GetManifestResourceStream("AssemblyName.ImageFile.jpg");
this.pictureBox1.Image = Image.FromStream(file);
(Source)
NOTE
You can either embed your images in a binary file (commonly your .exe) by setting the property Build Action to Embedded Resource, or leave them as separate files by setting Build Action to Content. If you leave as content, set Copy to Output Directory to True.
There's nothing in your code to say where the files are located so it's defaulting to somewhere the files aren't. If the files sit in the same location as your exe then try something like
imgNmae = "./image0" + i + ".png";
adjusting the relative path to account for where the files actually sit.
Related
I have an image file day.jpg in Resources folder and I want to access it in the code as string path not as byte[] img
Here's what I have tried.
string dayWallpaper = Assembly.GetExecutingAssembly().Location + #"..\..\Resources\day.jpg";
// Didn't found it
string dayWallpaper = Resource.day;
// Outputs byte[] and gives me an error
Then I tried to convert the byte[] to String didn't work as well
static byte[] SliceMe(byte[]? source, int pos)
{
byte[]? destfoo = new byte[source.Length - pos];
Array.Copy(source, pos, destfoo, 0, destfoo.Length);
return destfoo;
}
static string ByteToPath(path)
{
String file = Encoding.Unicode.GetString(SliceMe(path, 24)).TrimEnd("\0".ToCharArray());
return file
}
Outputs black screen
Later I search for the file
if (File.Exists(dayWallpaper))
{
do stuff
}
else
{
Console.WriteLine("File does not exists");
}
And gives me the else statement.
In the answer you posted to your question, the fact that your relative path works is an "accident" that would fail on any other device deploying your app because without the existence of the source code project the path doesn't exist. One good option is to mark the day.jpg file as Copy to Output Directory at which point most installer bundlers will pick it up and deploy it in your setup.exe, msi etc. If you are specifically using the Visual Studio IDE, you would do it like this:
Now, at runtime, to acquire the path to the copied file:
var srce = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "day.jpg");
However, there is more work to be done, because you state that you "want to store the image in a folder in the executable and the user could add more images later on." The present location of the file is not suitable for that purpose, so I would recommend the additional step of creating an AppData entry for the user to store their created content.
// Obtain a folder that "the user could add to later on".
var appData =
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
typeof(Program).Assembly.GetName().Name
);
Directory.CreateDirectory(appData);
Since you mention wanting to store the day.jpg image in that folder, go ahead and copy it to the AppData location (if not already there from a previous run of your app).
var dest = Path.Combine(appData, "day.jpg");
// Copy the image (if it's not there already) into folder that the user can add to.
if (!File.Exists(dest))
{
File.Copy(
sourceFileName: srce,
destFileName: dest
);
}
Alternatively, you could set the BuildAction to EmbeddedResource and manipulate the file as a byte stream and achieve the same end result.
I managed to do it this way
string resourcePath = Path.GetFullPath(Assembly.GetExecutingAssembly().Location + #"\..\..\..\..\Resources");
string dayWallpaper = resourcePath + #"\day.jpg";
Working on a project that does (or will eventually do) the following:
Access all images in a folder (for test phase using a folder in AppData called 'Test Images')
Place them in a new folder, where the image name is used to place it in or create a sub-folder using an algorithm
Save images in a 'List' so that when they have been saved, they can be displayed in a picturebox on the application - where they can be cycled through using prev/next buttons
The first two steps work fine, and I have checked that the images (only using two image files for the test phase) have been placed in subfolders.
I initialised an array of strings using the Directory.GetAllFiles() function in order to do this, meaning this array contains the paths of all the files that are being copied and manipulated. As a part of this process, I added each file path to the List<Bitmap> so they were able to be displayed in the picturebox.
However, whenever I try to run the function to display the image in the picturebox, the whole application crashes. No exception thrown or anything, just the whole thing stops working. I have no idea what is going on.
I've tried this using picbox.Image = to the element on the List<Bitmap> or using picbox.ImageLocation = to it's file path, but neither has been successful.
The code that should make this happen is shown below:
public void saveLatestImages()
{
//specific path for My Pictures only
string testImagesPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Test Images";
//if there is a Pictures folder
if (Directory.Exists(testImagesPath))
{
//get number of files in folder
int fileCount = Directory.GetFiles(testImagesPath).Count();
//more than one file in folder
if (fileCount > 0)
{
//create data structures to store file info
//filePaths holds path of each file represented as a string
string[] filePaths = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Test Images");
//for each file in Pictures...
for (int index = 0; index < fileCount; ++index)
{
//get name of image at current index
imageName = filePaths[index];
//separate the part relating to the patient name (everything before (DD/MM/YYYY))
string subSpecifier = imageName.Split('\\').Last();
subSpecifier = subSpecifier.Split('_')[0];
//add to root directory to form subfolder name
subDirectory = Path.Combine(rootDirectory, subSpecifier);
//subdirectory name formulated, check for pre-existing
//subfolder does not exist
if(!Directory.Exists(subDirectory))
{
//create it
Directory.CreateDirectory(subDirectory);
}
//otherwise, file will be added to existing directory
//take everything from end and folder\file division to get unique filename
string fileName = imageName.Split('\\').Last();
//add this to the existing subDirectory
fileName = Path.Combine(subDirectory, fileName);
//copy the image into the subfolder using this unique filename
File.Copy(imageName, fileName, true); //true gives instruction to overwrite any existing file with the same path
//add full filename to list of bitmap images
images.Add(new Bitmap(fileName));
//update the shortcut to the file in the image storage shortcut folder
shortcutDirectory = getShortcut(subSpecifier, fileName);
}
}
}
}
public void displayLatestImages()
{
//there are images in list
if (images.Count > 0)
{
//picbox defaults to first image
picboxImage.ImageLocation = Path.GetFileName(images.First().ToString());
}
//check for images before or after current image to enable buttons
checkFirstLast();
}
This shows everything that saves the images to their new file location, and should then allow the first image added to the List to be displayed.
Any advice on how to correct this would be greatly appreciated!
Thanks,
Mark
I have an issue with an C# application. I am trying to read some PDF files and load the data into a database.
The application make works good only when the PDF files are in a specific folder. the folder is the debug folder of the project.
I need to load the PDF files from any folder.
public string LecturaPDF(string nombreArchivo)
{
PdfReader lectorPDF = new PdfReader(nombreArchivo);
string TextoPuro = string.Empty;
string[] TextoDividido;
string TextoFinal = string.Empty;
for (int a = 1; a <= lectorPDF.NumberOfPages; a++)
{
ITextExtractionStrategy pdfParser =
new iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy();
TextoPuro = TextoPuro + PdfTextExtractor.GetTextFromPage(lectorPDF, a, pdfParser);
}
lectorPDF.Close();
TextoDividido = TextoPuro.Split('\n');
for (int b = 0; b < TextoDividido.Count(); b++)
{
if (TextoDividido[b].First()== '7')
{
TextoFinal = TextoFinal + TextoDividido[b] + ";";
}
}
return ';' + TextoFinal;
}
the error occur in this line PdfReader lectorPDF = new PdfReader(nombreArchivo);
the error say:
C:\user\me\MyDocuments\Projects\Project1\bin\debug\test.pdf not found
as file or resource
With this function I open a dialog box to select the file and call the function to read the pdf file:
private void cmdProcesar_Click(object sender, RoutedEventArgs e)
{
if (dialogoArchivo.ShowDialog().Value)
{
for (int a = 0; a < dialogoArchivo.FileNames.Count(); a++)
{
lblEstado.Dispatcher.Invoke(DispatcherPriority.Background, (Action)(() => lblEstado.Content =
"Procesando archivos contra Billing..."));
archivo.InsercionArchivo(dialogoArchivo.SafeFileNames[a], G_Fecha,
archivo.LecturaPDF(System.IO.Path.GetFullPath(dialogoArchivo.SafeFileNames[a])),
Convert.ToDouble(txtTarifa.Text),
conexion.ConexionOracle);
}
}
This is my first time with C# and I don't know why only works wwhen I read the files from the project debug folder
Any advice will appreciated
Thanks in advance
UPDATE
private void cmdProcesar_Automatico(object sender, RoutedEventArgs e)
{
string carpeta = "C:\\temp";
DirectoryInfo dir = new DirectoryInfo(carpeta);
FileInfo[] documentos = dir.GetFiles("*.pdf");
txtTarifa.Text = "1.48";
foreach (FileInfo archivopdf in documentos)
{
lblEstado.Dispatcher.Invoke(DispatcherPriority.Background, (Action)(() => lblEstado.Content =
"Procesando archivos contra Billing..."));
archivo.InsercionArchivo(archivopdf.Name, G_Fecha,
archivo.LecturaPDF(System.IO.Path.GetFullPath(archivopdf.Name)),
Convert.ToDouble(txtTarifa.Text),
conexion.ConexionOracle);
}
}
I change the function to automatically read all the file in a specific folder and process every file.
But I get the same error:
C:\user\me\MyDocuments\Projects\Project1\bin\debug\test.pdf not found
as file or resource
From the documentation of OpenFileDialog.SafeFileNames (emphasis mine):
Gets an array of file names and extensions for all the selected files in the dialog box. The file names do not include the path.
As it doesn't contain the path, the current path will be used which when you're running in the debugger will be bin\debug by default.
If you know the directory that the file should be chosen from you could add it to the file name (using Path.Combine) but if you would prefer the full path you can use the FileNames property which according to the documentation (again, emphasis mine):
Each file name includes both the file path and the extension. If no files are selected, this method returns an empty array.
In your context you'd need to change this line:
archivo.LecturaPDF(System.IO.Path.GetFullPath(dialogoArchivo.SafeFileNames[a])),
to
archivo.LecturaPDF(System.IO.Path.GetFullPath(dialogoArchivo.FileNames[a])),
EDIT
To answer the question in your edit - you are getting FileInfo objects for all pdf files in C:\temp but you are then using System.IO.Path.GetFullPath(archivopdf.Name) to get the file path to pass to archivo.LecturaPDF. The documentation for Path.GetFullPath states (emphasis mine again):
This method uses current directory and current volume information to fully qualify path. If you specify a file name only in path, GetFullPath returns the fully qualified path of the current directory.
Imagine that you have a FileInfo for the file c:\temp\example.pdf. When you call System.IO.Path.GetFullPath(archivopdf.Name) on that FileInfo you are essentially calling System.IO.Path.GetFullPath("example.pdf"). This will give the file name of example.pdf but it will use the current path for the path which in your case is C:\user\me\MyDocuments\Projects\Project1\bin\debug\ (the path your executable is running from).
This results in a fully qualified file name of C:\user\me\MyDocuments\Projects\Project1\bin\debug\example.pdf which isn't what you want and presumably doesn't exist.
As you already have a FileInfo object the solution is straightforward - you can use the FullName property directly without the need to call GetFullPath. The FullName property will give you the correct fully qualified name of c:\temp\example.pdf.
Your code should therefore read:
archivo.InsercionArchivo(archivopdf.Name, G_Fecha,
archivo.LecturaPDF(archivopdf.FullName),
Convert.ToDouble(txtTarifa.Text),
conexion.ConexionOracle);
In my method, I'm trying to save an image in a folder in the directory of my project. I have tried just putting the direct filepath of the folder, but that gives me an error when the project runs.
Is there a built-in extension of some kind in c# that would allow me to save this image in a folder in my directory; or way to simply access my directory without drilling to where my project is saved on my computer?
private void CreateBarcode()
{
var bitmapImage = new Bitmap(500,300);
var g = Graphics.FromImage(bitmapImage);
g.Clear(Color.White);
UPCbarcode barcode = new UPCbarcode(UPCbarcode.RandomGeneratedNumber(), bitmapImage, g);
string filepath=#"images/image1.jpg";
bitmapImage.Save(filepath,System.Drawing.Imaging.ImageFormat.Jpeg);
}
You can always use the AppData folder,
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Assuming the "Image" folder is in the root directory of your Project use:
Server.MapPath("~/Image" + filename)
you can check if the file already exist at a location by :
if (!File.Exists(filePath))
{
// Your code to save the file
}
I can guess that there is similarity in the name of the image file
try putting it under a different name
like
string filepath = # "images / blabla or AI.jpg";
Use this
string filepath= Application.StartupPath + "\images\image1.jpg";
bitmapImage.Save(filepath,System.Drawing.Imaging.ImageFormat.Jpeg);
I have an icon in my resource file , which I want to reference.
This is the code that needs that path to an icon file:
IWshRuntimeLibrary.IWshShortcut MyShortcut ;
MyShortcut = (IWshRuntimeLibrary.IWshShortcut)WshShell.CreateShortcut(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + #"\PerfectUpload.lnk");
MyShortcut.IconLocation = //path to icons path . Works if set to #"c:/icon.ico"
Instead of having an external icon file I want it to find an embedded icon file.
Something like
MyShortcut.IconLocation = Path.GetFullPath(global::perfectupload.Properties.Resources.finish_perfect1.ToString()) ;
is this possible ? if so how ?
Thanks
I think this should work, but I can't remember exactly (not at work to double check).
MyShortcut.IconLocation = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("YourNamespace.IconFilename.ico");
Just expanding on SharpUrBrain's answer, which didn't work for me, instead of:
if (null != stream)
{
//Fetch image from stream.
MyShortcut.IconLocation = System.Drawing.Image.FromStream(stream);
}
It should be something like:
if (null != stream)
{
string temp = Path.GetTempFileName();
System.Drawing.Image.FromStream(stream).Save(temp);
shortcut.IconLocation = temp;
}
I think it will help you in some what...
//Get the assembly.
System.Reflection.Assembly CurrAssembly = System.Reflection.Assembly.LoadFrom(System.Windows.Forms.Application.ExecutablePath);
//Gets the image from Images Folder.
System.IO.Stream stream = CurrAssembly.GetManifestResourceStream("ImageURL");
if (null != stream)
{
//Fetch image from stream.
MyShortcut.IconLocation = System.Drawing.Image.FromStream(stream);
}
The res protocol may be able to help you with this: http://msdn.microsoft.com/en-us/library/aa767740(v=vs.85).aspx
In WPF I have done this before:
Uri TweetyUri = new Uri(#"/Resources/MyIco.ico", UriKind.Relative);
System.IO.Stream IconStream = Application.GetResourceStream(TweetyUri).Stream;
NotifyIcon.Icon = new System.Drawing.Icon(IconStream);
The resource it is embedded, so incapsulated in a DLL assembly. So you cannot get its real path, you have to change your approach.
You would probably want to load the resource in memory and write it down to a temp file, then link it from there. Once the icon is is changed on the destination file, you can delete the icon file itself.