Xamarin.Essentials; FilePicker; Save a new file - xamarin

Using FilePicker one can open an existing file:
FileResult file = await FilePicker.PickAsync();
TextView textview = FindViewById<TextView>(Resource.Id.textview);
string path = file.FullPath;
var handle = File.Open(path, FileMode.OpenOrCreate);
byte[] data = new byte[10];
handle.Read(data, 0, 10);
Is there a similar way for saving a new file?

For now, the FilePicker plugin is only designed to pick existing files.
On Android and iOS, you could not do that. But on UWP, you could use the FileSavePicker.
Xamarin: https://learn.microsoft.com/en-us/xamarin/essentials/file-picker?tabs=android
UWP: https://learn.microsoft.com/en-us/windows/uwp/files/quickstart-save-a-file-with-a-picker

Related

Save file with custom extension using CreateChooser on Xamarin Android

I have to ask the user to choose a location and save the file with a custom extension (.tdr). I have set intent.SetType to */* and currently I have to save file without any extension. Can anyone please help me to resolve my issue?
Here is my code sample
Intent intent = new Intent();
intent.SetType("*/*");
intent.PutExtra(Intent.ExtraAllowMultiple, false);
intent.SetAction(Intent.ActionCreateDocument);
MainActivity.Instance.persistentStorageService.Write("DataToWrite", projectJson);
MainActivity.Instance.StartActivityForResult(Intent.CreateChooser(intent, "Save TRW Project File"), RequestCodeConstants.FilePickerSaveRequestCode);
In MainActivity.cs
System.IO.Stream output = ContentResolver.OpenOutputStream(data.Data);
var dataToWrite = persistentStorageService.Read("DataToWrite", typeof(string));
var buffer = Encoding.ASCII.GetBytes((string)dataToWrite);
output.Write(buffer, 0, buffer.Length);
output.Close();
result = buffer;
I want to save file in custom extension.
The issue is your MimeType, it needs to be set to octet for custom file types:
intent.SetType("application/octet");
Once you do that all you need to do is StartActivityForResult and you are done.
Activity.StartActivityForResult(intent, resultCode);
Make sure your extension type is a part of the file name itself, you can assign that through intent as well
intent.PutExtra(Intent.ExtraTitle, fileName);

How to show all images from a folder in Xamarin Cross-Platform app?

I am using VS 2017 to create a cross platform (UWP, Android, iOS) Xamarin app. I am trying to show all images from a folder on device as thumbnails (similar to gallery app, sample screenshot attached).
I have looked into WrapLayout sample code provided on Xamarin website (Link), but it's loading all images from internet using JSON
protected override async void OnAppearing()
{
base.OnAppearing();
var images = await GetImageListAsync();
foreach (var photo in images.Photos)
{
var image = new Image
{
Source = ImageSource.FromUri(new Uri(photo + string.Format("?width={0}&height={0}&mode=max", Device.OnPlatform(240, 240, 120))))
};
wrapLayout.Children.Add(image);
}
}
async Task<ImageList> GetImageListAsync()
{
var requestUri = "https://docs.xamarin.com/demo/stock.json";
using (var client = new HttpClient())
{
var result = await client.GetStringAsync(requestUri);
return JsonConvert.DeserializeObject<ImageList>(result);
}
}
I have also looked into Xamarin Media Plugin (Link), but it shows only one image at a time. Sample code -
await CrossMedia.Current.Initialize();
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
MainImage.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
But I am unable to find a way to implement these two (or any other methods) in such a way that I can create my own gallery section in my app.
You need to create an Activity in your specific platform. This activity will be launched as an intent throught your PCL project using, for instance, Dependency Services.
In this custom Activity you should have a GridView which fills its source from the current directory if the file fits your restrictions, such a specific extension, size, etc.
Finally, to get the selected image you just send the image path or whatever you need to the PCL project with DependencyService.

How to convert rad controls to images in silverlight

I'm using rad controls(charts and gridview) for developing an application,which i need to export the controls(each) into image.I have tried each control converting them into bytes format and send to webservice and converting them to images but sometime sending the byte data to service throws an error.Is any other way to convert each control into image.I have tried another way like.
Stream fileStream = File.OpenRead(#"\\HARAVEER-PC\TempImages\FlashPivot.png");
//PART 2 - use the stream to write the file output.
productChart.ExportToImage(fileStream, new Telerik.Windows.Media.Imaging.PngBitmapEncoder());
fileStream.Close();
It throwing me an error like cannot access to the folder TempImages.I have given sharing permissions to everyone but it doesn't access the folder.
Any solution is much appreciated.
private BitmapImage CreateChartImages()
{
Guid photoID = System.Guid.NewGuid();
string photolocation = #"D:\Temp\" + photoID.ToString() + ".jpg";
BitmapImage bi = new BitmapImage(new Uri(photolocation, UriKind.Absolute));
using (MemoryStream ms = new MemoryStream())
{
radChart.ExportToImage(ms, new PngBitmapEncoder());
bi.SetSource(ms);
}
return bi;
}

How to read files from project folders?

When the first time my app starts on a windows phone, I want to get some files(xml/images) from project folders and write them to the isolated storage .
How do I detect that my app is running for the first time?
How do I access file in project folders?
Here is another way to read files from your visual studio project. The following shows how to read a txt file but can be used for other file as well. Here the file is in the same directory as the .xaml.cs file.
var res = App.GetResourceStream(new Uri("test.txt", UriKind.Relative));
var txt = new StreamReader(res.Stream).ReadToEnd();
make sure your file is marked as Content.
If you mean project folders as in the folders in your visual studio project, I usually right click on the files and set the build action to 'Embedded Resource'. At runtime, you can read the data from the embedded resource like so:
// The resource name will correspond to the namespace and path in the file system.
// Have a look at the resources collection in the debugger to figure out the name.
string resourcePath = "assembly namespace" + "path inside project";
Assembly assembly = Assembly.GetExecutingAssembly();
string[] resources = assembly .GetManifestResourceNames();
List<string> files = new List<string>();
if (resource.StartsWith(resourcePath))
{
StreamReader reader = new StreamReader(assembly.GetManifestResourceStream(resource), Encoding.Default);
files.Add(reader.ReadToEnd());
}
To read the images you would need something like this to read the stream:
public static byte[] ReadAllBytes(Stream input)
{
byte[] buffer = new byte[32 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}

How can I insert an image with iTextSharp in an existing PDF?

I have an existing PDF and I can use FdFWriter to input to text boxes. It works well. Now I have an image. I have read the documentation and looked at many examples but they all create new documents and insert an image. I want to take an existing PDF and insert an image into either an image field or as the icon image of a button. I have tried but it corrupts the document.
I need to be able to take an existing document and put an image on it. I do not want to open, read, replace, and delete the original. This original changes and the name "original" only means the source file in this context. There are many PDF files like this that need an image.
Thank you for any help.
Edit - I am very thankful for the code below. It works great, but the problem for me is that the existing PDF has digital signatures on it. When the document is copied like this (into result.pdf) those signatures, while still present, have a different byte count or other item that is corrupted. This means the signatures, while they show up on result.pdf, have an icon next to them that state "invalid signature."
In case it matters I am using a Topaz signature pad to create my signatures, which has it's own security. Merely copying the PDF will not corrupt it but the process below will.
I am trying to put the image on the existing document, not a copy of it, which in this case matters.
Also, by signature, I mean handwritten, not pin numbers.
Thank you again.
EDIT - Can PdfSignatureAppearance be used for this?
EDIT - I seem to be able to do it with:
var stamper = new PdfStamper(reader, outputPdfStream,'1',true);
If you want to change the contents of an existing PDF file and add extra content such as watermarks, pagenumbers, extra headers, PdfStamper is the object you need. I have successfully used the following code to insert an image into an existing pdf file to a given absolute position:
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
class Program
{
static void Main(string[] args)
{
using (Stream inputPdfStream = new FileStream("input.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream inputImageStream = new FileStream("some_image.jpg", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new FileStream("result.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
{
var reader = new PdfReader(inputPdfStream);
var stamper = new PdfStamper(reader, outputPdfStream);
var pdfContentByte = stamper.GetOverContent(1);
Image image = Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(100, 100);
pdfContentByte.AddImage(image);
stamper.Close();
}
}
}
When you insert the image you have the possibility to resize it. You can take a look at transformation matrix in the iTextSharp documentation.
Here is a similar example whichi inserts an image on the page using the stamper:
Gmane iTex Mailing List Post
I could solve my problem by simply adding following lines to my signing code to add image
var image = iTextSharp.text.Image.GetInstance(#"C:\Users\sushil\Documents\sansign.jpg");
appearance.Acro6Layers = true;
appearance.SignatureGraphic = image;
appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;
As I was signing document with visible digital signature , now I can have both image and digital signature properties side by side
in the .net core6 that uses DDD try this declare class in Infrastructure Layer
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
public async Task<string> SignatureToPdf(string pathPdfFile, string
pathSignatureImage, string pathOutputName)
{
var webRootPath = hostingEnvironment.ContentRootPath;
if (!File.Exists(Path.Combine(webRootPath, pathPdfFile))) return
null;
await using Stream inputPdfStream =
new FileStream(Path.Combine(webRootPath, pathPdfFile),
FileMode.Open, FileAccess.Read, FileShare.Read);
await using Stream inputImageStream =
new FileStream(Path.Combine(webRootPath, pathSignatureImage), FileMode.Open, FileAccess.Read, FileShare.Read);
await using Stream outputPdfStream =
new FileStream(Path.Combine(webRootPath, pathOutputName),
FileMode.Create, FileAccess.Write, FileShare.None);
var reader = new PdfReader(inputPdfStream);
var stamper = new PdfStamper(reader, outputPdfStream);
var pdfContentByte = stamper.GetOverContent(1);
var image = Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(100, 100);
pdfContentByte.AddImage(image);
stamper.Close();
return "ok";
}
pdftk can do this. It's not a library but you can easily call it from your code as a .exe.
See stamp and background commands:
http://www.pdflabs.com/docs/pdftk-man-page/
ref: How to do mail merge on top of a PDF?

Resources