how load files, icons, xaml files embedded in the project? - c#

setting the file as "embedded resource" in the properties works like a char and is simple pload, like this:
var assembly = Assembly.GetExecutingAssembly();
string resourceName = assembly.GetManifestResourceNames()
.Single(str => str.EndsWith("svgImage.xaml"));
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
but if i change from "embedded resource" to just resource....it don't work anymore, i want load a svg image that i converted to a xaml file, to insert in the resource dictionary of a grid dynamically created in code
any tips?

Edit:
The example for text was wrong, I removed it.
The examples are for files that are placed directly in the project.
Image:
Add the image there as Resource.
MyBitmapImageProperty = new BitmapImage(new Uri("pack://application:,,,/ProjectName;component/Image.png"));
XAML:
<Image Source="{Binding MyBitmapImageProperty}" />

Related

path to image in deployed C# WPF app with ClickOnce

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.

Xamarin Forms Load image from folder inside project

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);

How can I stream simple text file using

I'm trying to read a simple text file using reflection just as a learning case. I'm not getting an error, but I'm also not getting the desired result of "hello world". The variable stream is coming back null.
string output = "";
var asm = Assembly.GetExecutingAssembly();
using (var stream = asm.GetManifestResourceStream("ConsoleApp1.data1.txt"))
{
if (stream != null)
{
var reader = new StreamReader(stream);
output = reader.ReadToEnd();
Console.WriteLine(output);
}
}
You're reading from a manifest resource, which means the text file needs to be embedded in the dll. Right click on the file and choose Properties, then set the Build Action to "Embedded Resource".

C# - How can I have a dynamic Image / BitmapSource accessible from XAML?

In my C# project I have a list of images which are resources compiled in the exe:
/Pics/Image1.png
/Pics/Image2.png
/Pics/Image3.png
...
In my code I process the images to match them to the theme of the application. The issue I am having is that I am trying to figure out an easy way to access these processed images in the XAML syntax.
This is how I typically access a resource image (pre-processed):
<Image Source="/Pics/Image1.png" />
So I would really like to access these processed images a similar way.
I tried a static dictionary like this:
<Image Source="{x:Static local:Theme.Images.ImageDictionary[/Pics/Image1.png]}" />
But this threw an error because it doesn't like the ".png", I haven't been able to get this working with dictionary keys. Not to mention this looks really ugly.
Ideally I would love to be able to "replace" the resource references, or create a resource at runtime (e.g. PicsProcessed/Image1.png) but haven't been able to figure a way to add or modify resources in a running C# application programmatically.
Any suggestions are really appreciated - thank you!
Have you tried creating a Bitmap then setting it as the image source? I think this should be easy. Give your image a name, say theImage. You can't possibly reference the image without giving it a name.
Try the following:
string path="/Pics/Image3.png";//path to the image
var bitmapImage=new Bitmap(new Uri(path));
theImage.source=bitmapImage;//set the bitmap as the source.
There are other ways you can achieve this though. Hope this helps?
It took a couple of days but I figured out a solution!
I moved all my images into another C# Project in the same solution, set to compile as a Class Libary DLL file called DynamicResources.dll (assembly name in the Project settings is "DynamicResources"). This project is added as a reference to the main project. As such I can access images in the XAML - clean and tidy:
<Image Source="/DynamicResources;component/pics/image1.png" />
Then in the post-build event for the main project, I rename the compiled .dll so it doesn't get loaded by the main .exe binary at launch:
copy "$(TargetDir)DynamicResources.dll" "$(TargetDir)DynamicResources.temp"
del "$(TargetDir)DynamicResources.dll"
Then I used a third-party library called Mono.Cecil to load the DynamicResources.temp file (DLL format), replace the resources, write it back to memory, then tell the application to load it:
public static void UpdateAssembly()
{
string dllFile = "DynamicResources.temp";
string dllNamespace = "DynamicResources";
var asm = AssemblyDefinition.ReadAssembly(dllFile);
var module = asm.Modules.FirstOrDefault();
var resources = module.Resources;
var dllResource = (EmbeddedResource)(resources.FirstOrDefault());
var dllResourceReader = new ResourceReader(dllResource.GetResourceStream());
var newResourceOutputStream = new MemoryStream();
var newResourceWriter = new ResourceWriter(newResourceOutputStream);
foreach (DictionaryEntry dllResourceEntry in dllResourceReader)
{
var image = (BitmapSource)new ImageSourceConverter().ConvertFrom(dllResourceEntry.Value);
Color foreground = (Color)ColorConverter.ConvertFromString("#FFFFFF");
var processed = (WriteableBitmap)ColorizeImage(image, foreground); // Your image processing function ?
newResourceWriter.AddResource(dllResourceEntry.Key.ToString(), BitmapToByte(processed));
}
newResourceWriter.Close();
var newResource = new EmbeddedResource(dllResource.Name, dllResource.Attributes, newResourceOutputStream.ToArray());
module.Resources.Remove(dllResource);
module.Resources.Add(newResource);
var woutput = new MemoryStream();
asm.Write(woutput);
var doutput = woutput.ToArray();
Assembly assembly = Assembly.Load(doutput);
}
public static MemoryStream BitmapToByte(BitmapSource bitmapSource)
{
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
var frame = System.Windows.Media.Imaging.BitmapFrame.Create(bitmapSource);
encoder.Frames.Add(frame);
var stream = new MemoryStream();
encoder.Save(stream);
return stream;
}
public static void AttachAssembly(string myAsmFileName)
{
Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + myAsmFileName); // LoadFrom
AppDomain.CurrentDomain.Load(assembly.GetName());
}
Important note: When iterating through resources, they become lowercase, so you must use lowercase file and folder names.

Path to an embedded resource file

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.

Categories

Resources