I have problem with set correct file path to image in my project which is deployed with ClickOnce.
The 3rd party library for generating pdf documents needs path of image as input for method.
public Image AddImage(string fileName);
I'm using following library for generating pdf documents - https://www.nuget.org/packages/PDFsharp-MigraDoc-gdi/1.50.5147/
The image is located in class library project which is linked to WPF project.
Image has following settings in visual studio.
But after install, image does not appear in instalation location.
If it would appear I would use following code for get path of image.
string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); \\+image name
What am I doing wrong?
Should I use another approach?
Thanks to #IlikedtheoldStackOverflow I manage to include image to solution as embedded resource, which is also working after ClickOnce publish.
I reproduced steps from from pdfsharp doc -pdfsharp.net/wiki/MigraDoc_FilelessImages.ashx
Changed Build Action to Embedded resource
Created correct path to image in format - Namespace.FolderWhereIsImage.NameOfImage.png
SAMPLE CODE from pdfsharp doc
private string MigraDocFilenameFromByteArray(byte[] image)
{
return "base64:" + Convert.ToBase64String(image);
}
private byte[] LoadImage(string name)
{
var assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(name))
{
if (stream == null)
throw new ArgumentException("No resource with name " + name);
int count = (int)stream.Length;
byte[] data = new byte[count];
stream.Read(data, 0, count);
return data;
}
}
byte[] image = LoadImage("SampleProject.Resources.logo.png");
string imageFilename = MigraDocFilenameFromByteArray(image);
row.Cells[2].AddParagraph().AddImage(imageFilename);
"SampleProject.Resources.logo.png" .. Resources is name of folder in the project and SampleProject is project name.
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";
I have a problem. I am trying to save an Image to a folder in my project (not the Resources folder!) and load theimage from that folder into an Image holder as source. I want the image to be saved in a folder called: TempImages and my app name is MyApp. Here is the code I have now:
Saving:
using (var image = args.Surface.Snapshot())
using (var data = image.Encode(SKEncodedImageFormat.Png, 80))
using (var stream = File.OpenWrite(Path.Combine("MyApp.TempImages", "CreatedImage.png")))
{
data.SaveTo(stream);
}
Opening:
string resourceID = string.Format("MyApp.TempImages.CreatedImage.png");
Assembly assembly = GetType().GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream(resourceID);
imgCanvas.Source = ImageSource.FromFile(resourceID);
But I think that File.OpenWrite a local file on my pc means, but I am not sure. And therefore I am not sure if I am opening the file correctly. Now I get the error that the save path doesn't exist.
How can I fix this?
you should be able to create any folder structure you want within one of the app writeable paths
var path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var folder = Path.Combine(path,"MySpecialFolder");
Directory.CreateDirectory(folder);
var file = Path.Combine(folder,"MyImage.png");
File.WriteAllBytes(file,data);
var image = File.ReadAllBytes(file);
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.
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.