Xamarin Forms Load image from folder inside project - c#

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

Related

Get image file path from resources

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

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.

Zip up collection of files and move to target location

I'm collecting all my files in a target directory and adding them to a zip folder. Once this zip is made and no more files need adding to it, I want to move this zip folder to another location.
Here is my code for doing all of the above:
var targetFolder = Path.Combine(ConfigurationManager.AppSettings["targetFolder"], "Inbound");
var archiveFolder = ConfigurationManager.AppSettings["ArchiveFolder"];
// get files
var files = Directory.GetFiles(targetFolder)
.Select(f => new FileInfo(f))
.ToList();
// places files into zip
using (var zip = ZipFile.Open("file.zip", ZipArchiveMode.Create))
{
foreach (var file in files)
{
var entry = zip.CreateEntry(file.Name);
entry.LastWriteTime = DateTimeOffset.Now;
using (var stream = File.OpenRead(file.ToString()))
using (var entryStream = entry.Open())
stream.CopyTo(entryStream);
}
}
// move the zip file
File.Move("file.zip", archiveFolder );
Where I'm falling down is the moving of the zip folder. When my code gets to File.Move I get an error telling me it can not create something that already exists. This happen even when I hard code in my archive folder location instead of getting it from my config.
What am I doing wrong with this?
You need to specify the destination file name as well as directory:
File.Move("file.zip", Path.Combine(archiveFolder, "file.zip"));

Saving images to a project folder in asp.net/c#

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

Bind images to listbox with datatemplate from app package folder

Hi I need bind images to listbox but when I try it I get FILE NOT FOUND but file is stored in application package in folder layoutGraphics. I try put files to default folder but I get same result anyone know what is bad?
var file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("ms-appx:///layoutGraphics/offline.png");
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
var img = new BitmapImage();
img.SetSource(fileStream);
ImgSource = img;
// property
private BitmapImage _imgSource;
public BitmapImage ImgSource
{
get { return _imgSource; }
set
{
_imgSource = value;
OnPropertyChanged("MyDatasMessagesUserList");
}
}
Or anyone know better solution how I can bind imagess from app folder to my listbox with datatemplate?
Windows.Storage.ApplicationData.Current.LocalFolder is retriving file from the application storage not the package. For the package folder you need to use Windows.ApplicationModel.Package.Current.InstalledLocation. Also the GetFileAsync take just the name of a file not a full path.
Here is the code to acomplish what you want:
var layoutGraphiceFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("layoutGraphics")
var file=await layoutGraphiceFolder.GetFileAsync("offline.png");
Another way to do it with the full path is:
var file=await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///layoutGraphics/offline.png"));

Categories

Resources