Hi,
Our Xamarin Forms app has a Gallery where we can display collections of images on a FlexLayout. For jpgs we use thumbnails. The user can click on a thumbnail to see the full image full screen.
We also have a collection of PDFs which we use the SF PDFViewer to fill in, draw on and other manipulations and finally to save.
I've been tasked with adding a representation of the PDFs to the Gallery on a row of their own. How can I get a thumbnail of a PDF using Syncfusion tools? Or do you have an alternative suggestion for representing up to, say, 5 PDFs, on a row of a FlexLayout? (the 5 representations of the PDFs can scroll off the device)
Thanks for your help.
Will
|
We also have a collection of PDFs which we use the SF PDFViewer to fill in, draw on and other manipulations and finally to save.I've been tasked with adding a representation of the PDFs to the Gallery on a row of their own. How can I get a thumbnail of a PDF using Syncfusion tools? |
We assume that you want to show the first page of the PDF document as a thumbnail image in your gallery to represent each PDF files. The SfPdfViewer.ExportAsImage method can be used to convert the first page of the PDF to image and the image can be shown as thumbnail.
Please find the UG link for Export as image ,
https://help.syncfusion.com/xamarin/pdf-viewer/export-as-image Please let us know whether this solution satisfies your requirement. If not, please let us know more details about your requirement and how you want to achieve it. |
|
Or do you have an alternative suggestion for representing up to, say, 5 PDFs, on a row of a FlexLayout? (the 5 representations of the PDFs can scroll off the device) |
We cannot think of any other way better than thumbnails to represent a PDF file in a gallery. Kindly let us know if converting the first page of each PDF to thumbnail using the ExportAsImage API as we mentioned above satisfies your requirement |
Hello Vikram D,
That looks like a great solution to my question. Unfortunately I need to deal with some obstinate bugs and have not been able to fully test your solution. I hope to get back to this soonest.
Regards,
Will
Hi Vikram D,
What is the current method to read a file in the local file system and convert it to a stream?
I saw ways to read it from an embedded pdf.
Thanks!
Will
Hello Vikram D.
Thanks for your help. But I am not there quite yet.
1) Thanks to you , I can read a PDF from the system files. As proof that it worked, I have displayed a portion of it in a page.
2) Now I try to take the PDF that was just read in and create a jpg from the first page. That does not display.
3) In case I messed up the display portion, I wrote out the jpg and read it in again and tried to display it. That does not work.
Of the following two code snippets, one is the code-behind that manipulates the PDF to JPG (and the rest). Then there is the XAML.
public async void TestForPDFs()
{
long PrjinforID = Util._selectedProjectAll.project.prjinfoID;
// the next line hits sqlite for the PDFs related to the project. There is only one PDF in this case.
List<Docs> myDocs = Table_Docs.getDocsByProject(PrjinforID);
string fileToGet = "";
string imageName = "";
if (myDocs.Count > 0)
{
// The sqlite table has, among other things, the local path to the PDF. That gets stored in fileToGet.
fileToGet = myDocs[0].DocsPath;
// The following is from some Syncfusion code. It works because I can display the PDF.
if (Device.OS == TargetPlatform.Windows || Device.OS == TargetPlatform.WinPhone)
//Obtain the PDF stream from the UWP implementation of IFileHelperService. It is an asynchronous process
//Since constructor cannot be async, this process must be done in another method
SetFileStreamAsync(fileToGet);
else
pdfStream = DependencyService.Get<IFileHelperService>().GetFileStream(fileToGet);
}
// now let's take the pdfStream and turn it into a jpg
// https://help.syncfusion.com/xamarin/pdf-viewer/export-as-image
//Initialize the SfPdfViewer
SfPdfViewer pdfViewerControl = new SfPdfViewer();
//Load the PDF document as stream
pdfViewerControl.LoadDocument(PdfStream);
//Export the page of PDF document to image stream with the given index;
Stream ImageFromPDFstream = pdfViewerControl.ExportAsImage(0);
GM.FileImgFromPDF = ImageSource.FromStream(() => ImageFromPDFstream);
// some of the original code=> ImageSource.FromStream(Func < System.IO.Stream > stream);
//===================================================
// This part writes the captured image to the android disk
// it also takes the name of the PDF and changes .pdf to .jpg
imageName = fileToGet.Replace("pdf", "jpg");
using (Stream fileHandler = File.OpenWrite(imageName))
{
byte[] imageBuffer = new byte[ImageFromPDFstream.Length];
ImageFromPDFstream.Read(imageBuffer, 0, (int)ImageFromPDFstream.Length);
await fileHandler.WriteAsync(imageBuffer, 0, imageBuffer.Length);
}
// so, that is supposed to write the image out.
// now lets read it in and display it.
GM.FileImg = ImageSource.FromFile(imageName);
}
And here is the XAML:
<Grid x:Name="pdfViewGrid">
<syncfusion:SfPdfViewer x:Name="pdfViewerControl" InputFileStream="{Binding PdfStream }"
WidthRequest="100" HeightRequest="200"/> // this only shows the top bit of the PDF, but enough to show me that it got there.
</Grid>
<Label Text="FileImg"/>
<Image Source="{Binding GM.FileImg}"
Aspect="AspectFit" HeightRequest="60"
WidthRequest="90"/>
<Label Text="FileImgFromPDF"/>
<Image Source="{Binding GM.FileImgFromPDF}"
Aspect="AspectFit" HeightRequest="60"
WidthRequest="90"/>
=================================
I got these two messages in the debug output:
[Drawable] Unable to decode stream: android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.
[ImageView] resolveUri failed on bad bitmap uri: /data/user/0/com.itraxonline.itraxmobile/files/Pictures/2107K001_i-Trax_Work_Authorization_Form_Siging16050310351624310052_2021Aug26_092048.jpg
The part that says "Failed to create image decoder ..." causes me concern.
The uri, is where I saved the jpg to.
I have also included a copy of the PDF being tested with. Does it make a difference in this case if it is a form with filled in fields? This is the original form with no fields filled in.
Any further questions please send them my way.
I sure appreciate your help!
Regards,
Will
Hello Vikram,
Thanks again for your reply.
The attached 7z file is an app that is supposed to read an embedded PDF, write it out (to prove that it got read), then convert the first page of the PDF into an image and display it. (I really only need the image displayed, but for testing I also display a part of the PDF)
If you search for
pdfViewerControl.LoadDocument(PdfStream);
1) You will see the line where the app crashes. It is different than what I previously described because I was not able to replicate it on a smaller scale.
2) I used an embedded file because I was not able to store a pdf locally (in a timely manner). What I really need is to read a local PDF, convert the first page into an image and display it. (actually, I will be reading the Paths for several PDFs from SQLite, getting an image of page 1 of each and displaying them in a CollectionView. I trust that if I can do this for one file, the rest will follow. The general flow of our app is to download master copies of several PDF files, have them modified by the app (by our staff or clients - fill in form fields, draw diagrams,...), stored locally as well as uploaded to our server. The locally stored files may be used to create an image for each PDF and display - as I am working on here. I include this bit to give you more context.)
In my app I am using 19.2.0.56
In the sample app - 19.2.0.57
I am loading it onto a Samsung S10e using Android 11.
Best Regards,
Will
PS. I tried several times to upload my zipped project for the app but it repeatedly failed. I even changed the extension as sometimes that helps. So, I put the sample app on OneDrive. Please get the samples zip file from there.
Now I get "Forum submission was unsuccessful" .
What??
----------------
So, I removed the OneDrive link and will try again.
Now I can't even put a check in the "I am not a Robot" box.
The next step is to go to a different pc and try it all again. If you get this, you will know it worked.
This looks promising. I copied the zip to my office computer and was then able to upload it to this submission. Now I'll try to submit it.
Hello Vikram,
Thanks for your thorough revision to my sample app. I appreciate the effort that you put in to it.
When I downloaded and unzipped it, I ran it immediately and got an error at this line:
Java.IO.FileOutputStream outs = new Java.IO.FileOutputStream(file);
When I searched for
Java.IO.FileOutputStream
the only exceptions that is says it throws are:
FileNotFoundException
SecurityException
The message that I am getting is:
**System.Reflection.TargetInvocationException:** 'Exception has been thrown by the target of an invocation.'
I googled the Exception and also the code but found nothing useful.
Here is the class involved. I did some slight reformatting. Otherwise it is as I received it. I also changed the min and max Android versions to 8 and 11. But that did not change the results.
I test on a Samsung Galaxy S10e real phone.
Regards,
Will
namespace PDFToImage.Droid
{
public class SaveAndroid : ISave
{
public string Save(MemoryStream stream)
{
string root = null;
string fileName = "SavedDocument.jpg";
if (Android.OS.Environment.IsExternalStorageEmulated)
{
root = Android.OS.Environment.ExternalStorageDirectory.ToString();
}
string newpath = root + "/Syncfusion";
Java.IO.File myDir = new Java.IO.File(root + "/Syncfusion");
if (myDir.Exists() == false)
{
myDir.Mkdir();
}
Java.IO.File file = new Java.IO.File(myDir, fileName);
string filePath = file.Path;
if (file.Exists())
{
file.Delete();
}
// Following gives: **System.Reflection.TargetInvocationException:** 'Exception has been thrown by the target of an invocation.'
Java.IO.FileOutputStream outs = new Java.IO.FileOutputStream(file);
outs.Write(stream.ToArray());
var ab = file.Path;
outs.Flush();
outs.Close();
return filePath;
}
}
}
Thanks for looking at this again.
Hello Vikram,
Congratulations! You managed to guide me thru that process.
In Settings I had to enable "Allow management of all files." Before that I had only enabled "Allow access to media only."
Now, as long as I can transform what you did in the sample app into our main app, we'll be golden.
Thanks so much for your help. This last one had such a seemingly unrelated error message, that I may have never solved it.
Regards,
Will