Imagine being paid to improve your favorite CMS!

It could be you! Umbraco HQ are hiring and are looking for both talents and senior developers. Wonderful workplace, friendly colleagues and competitive salary.

Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Laurens Gregoir 134 posts 566 karma points
    Apr 19, 2017 @ 13:53
    Laurens Gregoir
    0

    Preview PDF files as images on your website

    Hi all,

    I've found this neat article of Damiaan on his blog about displaying PDFs as an image on your website.

    http://blog.dampee.be/post/2017/01/09/Preview-PDF-files-as-images-on-your-website.aspx

    Damiaan already informed me that I can donwload the nuget file and extract it by changing the extension to .zip. Then you only need to add the DLL files to the /bin folder.

    But now how can I integrate this in my website directly from within Umbraco? (So without using Visual Studio).

    Thanks and kr,

    Laurens

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 19, 2017 @ 17:41
    Damiaan
    1

    Hi Laurens

    It's pretty easy. You just use the ImageProcessor plugin, which will call the plugin i've written.

    If you have an image just add ?width=800 in the image URL (or use GetCropUrl) and you'll get an image of 800 width. If the input is a PDF, the plugin will be called by ImageProcessor. You don't need to do anything else.

    Should work flawless

    Kind regards Damiaan

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 14:40
    Laurens Gregoir
    0

    Hi Damiaan,

    Just imported the DLL to my bin folder of our dev environment. Sounds silly, but how can I call the pdf be shown as an image?

    Thanks,

    Laurens

    EDIT:

    Tried the following from https://github.com/dampee/ImageProcessor.Plugins.Pdf/

    /myfile.pdf?format=jpg&width=500

    And it fetches my pdf URL, but it doesn't displays it as an image. This leaves me to believe that the DLL isn't called.

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 21, 2017 @ 15:15
    Damiaan
    0

    If you try the same thing with a image, does it work?

    If so, the plug-in is not loaded into ImageProcessor (and we have to find out why).

    If not, then imageprocessor is not working for some reason.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 15:18
    Laurens Gregoir
    0

    The imageprocessor is installed by default right?

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 21, 2017 @ 15:19
    Damiaan
    0

    In umbraco? Yes it is.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 15:28
    Laurens Gregoir
    0

    Hmm ok, thought so :)

    This is how I load in the pdf:

    <img src="@Umbraco.TypedMedia(@temp.value).Url?format=jpg&width=500"/>
    

    @temp.value is the media ID of the PDF.

    And it pulls the correct URL, but doesn't load the image/ or plugin: /media/xxxx/2016-half-year-report-en.pdf

  • Sven Geusens 105 posts 607 karma points
    Apr 21, 2017 @ 15:45
    Sven Geusens
    0

    Hey, Damiaan's minion here

    try

    <img src="@(Umbraco.TypedMedia(@temp.value).Url)?format=jpg&width=500"/>
    

    Maybe razor is having problems with the ?

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 15:48
    Laurens Gregoir
    0

    Hi Sven,

    Afraid it's not working :( I don't get any errors and the '?' shouldn't be a problem as I'm using it for Imagegen.

  • Sven Geusens 105 posts 607 karma points
    Apr 21, 2017 @ 15:51
    Sven Geusens
    0

    Did you supply a ghostscript dll as instructed on the github readme?

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 15:52
    Laurens Gregoir
    0

    It's in the bin folder. Do I need to call it (or anything else) in the razor script?

    enter image description here enter image description here

  • Sven Geusens 105 posts 607 karma points
    Apr 21, 2017 @ 16:05
    Sven Geusens
    0

    Just to make sure.

    Files that should be present in your bin

    • Ghostscript.NET.dll
    • ImageProcessor.Plugins.Pdf.dll
    • ImageProcessor.dll
    • gsdll32.dll or gsdll64.dll

    If all those files are in your bin, it should work out of the box without any other configuration.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 16:11
    Laurens Gregoir
    0

    Those are in there. Added the Ghostscript.NET.dll after your previous reply.

    I have both the 32b or 64b. I'll disable one of them.

    EDIT1: Not working :( EDIT2: Switching doesn't change it neither.

    I have the feeling that the dll isn't called properly.

  • Sven Geusens 105 posts 607 karma points
    Apr 21, 2017 @ 16:14
    Sven Geusens
    0

    I will let Damiaan pick this up when he has the time as I am out of ideas. Sorry I couldn't get it to work.

    Edit: just out of curiosity, what actual url do you get on the html page when you use <img src="@Umbraco.TypedMedia(@temp.value).GetCropUrl(width:500)"/>

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 16:17
    Laurens Gregoir
    0

    No problem, thanks for trying. :)

    I'm going to look from where it's coming as well. Could maybe be another plugin that's acting up.

    The DLL's are loaded in correctly from what I can see. If I find something, I will post it here as well!

  • Laurens Gregoir 134 posts 566 karma points
    Apr 21, 2017 @ 16:22
    Laurens Gregoir
    0

    Aha, getting there I believe. Seems I'm receiving this error when I call directly the URL of the PDF with the '?' parameters behind it.

    Server Error in '/' Application.
    This managed library is running under 32-bit process and requires 32-bit Ghostscript native library installation on this machine! To download proper Ghostscript native library please visit: http://www.ghostscript.com/download/gsdnld.html
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
    
    Exception Details: Ghostscript.NET.GhostscriptLibraryNotInstalledException: This managed library is running under 32-bit process and requires 32-bit Ghostscript native library installation on this machine! To download proper Ghostscript native library please visit: http://www.ghostscript.com/download/gsdnld.html
    
    Source Error:
    
    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
    
    Stack Trace:
    
    
    [GhostscriptLibraryNotInstalledException: This managed library is running under 32-bit process and requires 32-bit Ghostscript native library installation on this machine! To download proper Ghostscript native library please visit: http://www.ghostscript.com/download/gsdnld.html]
       Ghostscript.NET.GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense licenseType, GhostscriptLicense licensePriority) +265
       ImageProcessor.Plugins.Pdf.PdfRasterizer..ctor(Int32 xDpi, Int32 yDpi) +83
       ImageProcessor.Plugins.Pdf.PdfFormat.Load(Stream stream) +181
       ImageProcessor.ImageFactory.Load(Stream stream) +97
       ImageProcessor.Web.HttpModules.<ProcessImageAsync>d__34.MoveNext() +2399
       System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
       System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
       System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar) +71
       System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +9770477
    
  • Dave Woestenborghs 2368 posts 6643 karma points mvp c-trib
    Apr 22, 2017 @ 12:19
    Dave Woestenborghs
    0

    Hi Laurens,

    I just had a look at the GhostScript.NET source code. The exception is thrown from the method Ghostscript.NET.GhostscriptVersionInfo.GetLastInstalledVersion. The source code for that you can find here : https://github.com/jhabjan/Ghostscript.NET/blob/93776b5f0c6284c27d69488227c07660b868734d/Ghostscript.NET/GhostscriptVersionInfo.cs#L288

    This method calls the method GetInstalledVersions which can be found here : https://github.com/jhabjan/Ghostscript.NET/blob/93776b5f0c6284c27d69488227c07660b868734d/Ghostscript.NET/GhostscriptVersionInfo.cs#L153

    If you look at the method it will search inside the machine registry for some keys. I think that is the issue.

    Can you run this code from your view to see if this returns installed versions :

    List<GhostscriptVersionInfo> gsVersions =
        GhostscriptVersionInfo.GetInstalledVersions()
    

    Dave

  • Laurens Gregoir 134 posts 566 karma points
    Apr 24, 2017 @ 07:56
    Laurens Gregoir
    0

    Hi Dave,

    Thanks!

    When I add this piece of code in my view it's resulting in an error.

    But I have installed the DLL's on my live environment and on that it's working without any issues.

    enter image description here

  • Laurens Gregoir 134 posts 566 karma points
    Apr 22, 2017 @ 08:50
    Laurens Gregoir
    0

    So I've updated the gsdll32.dll and gsdll64.dll in my /bin folder to be sure it's up to date.

    Restarted the IIS pool and still the same error stating it's not installed :/

    Any ideas what I might be overlooking?

    EDIT: Also to note, I have all the needed DLL's in my /bin folder.

    But it's like the gsdll64.dll is not called correctly or can't be found for some reason.

    It's maddening :p

  • Laurens Gregoir 134 posts 566 karma points
    Apr 24, 2017 @ 07:58
    Laurens Gregoir
    0

    Update:

    Uploaded the DLL's to my live site which is a true virtual machine. And installed the Ghostscript software on it as well.

    When I do a direct call and just use the code it is working without any problems.

    The current DEV environment is a Plesk box that run IIS and SQL. So I can't install software other then just adding DLL files to the webfolder's /bin.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 24, 2017 @ 08:09
    Laurens Gregoir
    0

    So now it's working on my live environment, but I see the following problem.

    In the logs I see that the DLL is throwing an exception 0X8007000B. And according different sources its stating that I need to set my IIS pool to 32B.

    When I do that, the DLL works, but my homepage stops working!

    Logs:

    System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
       at GhostscriptSharp.GhostscriptWrapper.CreateAPIInstance(IntPtr& pinstance, IntPtr caller_handle)
       at GhostscriptSharp.GhostscriptWrapper.CallAPI(String[] args)
       at GhostscriptSharp.GhostscriptWrapper.GeneratePageThumb(String inputPath, String outputPath, Int32 page, Int32 width, Int32 height)
       at MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator.Generate(String file)
     2017-04-24 00:53:56,131 [P9416/D2/T42] INFO  MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator - Completed Creating Thumbnail (took 26ms)
     2017-04-24 00:59:56,990 [P9416/D2/T16] INFO  umbraco.BusinessLogic.Log - Log scrubbed.  Removed all items older than 2017-04-23 00:59:56
     2017-04-24 02:55:08,124 [P9416/D2/T39] INFO  MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator - Started Creatning Thumbnail
     2017-04-24 02:55:08,152 [P9416/D2/T39] ERROR MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator - Faled generat pdf thumbnail
    System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
       at GhostscriptSharp.GhostscriptWrapper.CreateAPIInstance(IntPtr& pinstance, IntPtr caller_handle)
       at GhostscriptSharp.GhostscriptWrapper.CallAPI(String[] args)
       at GhostscriptSharp.GhostscriptWrapper.GeneratePageThumb(String inputPath, String outputPath, Int32 page, Int32 width, Int32 height)
       at MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator.Generate(String file)
     2017-04-24 02:55:08,152 [P9416/D2/T39] INFO  MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator - Completed Creating Thumbnail (took 27ms)
     2017-04-24 04:59:57,024 [P9416/D2/T16] INFO  umbraco.BusinessLogic.Log - Log scrubbed.  Removed all items older than 2017-04-23 04:59:56
     2017-04-24 08:08:15,220 [P9416/D2/T64] INFO  MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator - Started Creatning Thumbnail
     2017-04-24 08:08:16,110 [P9416/D2/T64] ERROR MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator - Faled generat pdf thumbnail
    System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
       at GhostscriptSharp.GhostscriptWrapper.CreateAPIInstance(IntPtr& pinstance, IntPtr caller_handle)
       at GhostscriptSharp.GhostscriptWrapper.CallAPI(String[] args)
       at GhostscriptSharp.GhostscriptWrapper.GeneratePageThumb(String inputPath, String outputPath, Int32 page, Int32 width, Int32 height)
       at MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator.Generate(String file)
     2017-04-24 08:08:16,110 [P9416/D2/T64] INFO  MissingCode.Umbraco.PdfThumbnail.ThumbnailGenerator - Completed Creating Thumbnail (took 890ms)
    

    Then when you look at the media folder it is trying to convert from PDF to JPG I see a few temp PDF files that are filling up the drive.

    enter image description here

    Which is the exact same issue that I had with Yakov , but this plugin does not fills up the drive as fast as before. With the previous plugin the grow rate was continuous and filled up the drive after like 2 days.

    https://our.umbraco.org/projects/backoffice-extensions/pdf-thumbnail/

    But we are making progress, the PDFs are all converted to JPG and it shows it nicely. But I wonder where the DLL stores the converted JPG's?

    EDIT: Temp PDFs where still being created by the pdf-thumbnail package. Had nothing to do with the DLL from Damiaan.

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 24, 2017 @ 08:18
    Damiaan
    1

    This should not be happening. The converted images are stored by imageprocessor. Maybe Ghostscript stores temporary folders. I'll look at a website where we deployed the package and see if we have the same behaviour.

    The JPG's are stored in Imageprocessor's /App_Data/Cache folder.

    Concertning the exception, you are still using the old plugin "MissingCode.Umbraco.PdfThumbnail". You don't need to call the thumbnailGenerator. Everything is handled by ImageProcessor when using our plugin.

    In fact, it's a plugin for imageprocessor, allowing imageprocessor to have PDF's as an input format.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 24, 2017 @ 08:36
    Laurens Gregoir
    0

    Hi Damiaan,

    Indeed, my mistake. The old plugin was used in a different script as well. Changed it to yours and the error is gone at the moment.

    I also believe that the random PDFs that are created are from that plugin as well. As that one does the same thing as yours, but stores the converted JPG file in the original media folder.

    And when it fails creating said JPG, it tries again & again until your harddrive is full or it succeeds, it does not however clean up or remove the old random PDF's...

    With this gone, your DLL is working. Now I only see this error. Something I can ignore I believe?

     2017-04-24 10:30:21,256 [P9416/D3/T66] ERROR Umbraco.Core.UmbracoApplicationBase - An unhandled exception occurred
    Ghostscript.NET.GhostscriptAPICallException: An error occured when call to 'gsapi_new_instance' is made: -100
       at Ghostscript.NET.Interpreter.GhostscriptInterpreter.Initialize()
       at Ghostscript.NET.Viewer.GhostscriptViewer.Open(String path, GhostscriptVersionInfo versionInfo, Boolean dllFromMemory)
       at Ghostscript.NET.Rasterizer.GhostscriptRasterizer.Open(Stream stream, GhostscriptVersionInfo versionInfo, Boolean dllFromMemory)
       at ImageProcessor.Plugins.Pdf.PdfRasterizer.Rasterize(Stream pdfStream, Int32 pageNumber)
       at ImageProcessor.Plugins.Pdf.PdfFormat.Load(Stream stream)
       at ImageProcessor.ImageFactory.Load(Stream stream)
       at ImageProcessor.Web.HttpModules.ImageProcessingModule.<ProcessImageAsync>d__34.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar)
       at System.Web.HttpApplication.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar)
    

    Many thanks so far!

    Laurens

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 24, 2017 @ 10:25
    Damiaan
    1

    Never had an issue like mentioning gsapi_new_instance. I just merged in a pull request and testing it right now. Give me a few hours to give feedback.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 24, 2017 @ 10:42
    Laurens Gregoir
    0

    Of course, thank you!

    If it can help, this is the most recent entry of the error code.

    Ghostscript.NET.GhostscriptAPICallException: An error occured when call to 'gsapi_new_instance' is made: -100
       at Ghostscript.NET.Interpreter.GhostscriptInterpreter.Initialize()
       at Ghostscript.NET.Viewer.GhostscriptViewer.Open(String path, GhostscriptVersionInfo versionInfo, Boolean dllFromMemory)
       at Ghostscript.NET.Rasterizer.GhostscriptRasterizer.Open(Stream stream, GhostscriptVersionInfo versionInfo, Boolean dllFromMemory)
       at ImageProcessor.Plugins.Pdf.PdfRasterizer.Rasterize(Stream pdfStream, Int32 pageNumber)
       at ImageProcessor.Plugins.Pdf.PdfFormat.Load(Stream stream)
       at ImageProcessor.ImageFactory.Load(Stream stream)
       at ImageProcessor.Web.HttpModules.ImageProcessingModule.<ProcessImageAsync>d__34.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar)
       at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
       at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
    
  • Damiaan 380 posts 1044 karma points c-trib
    Apr 24, 2017 @ 10:42
    Damiaan
    100

    You don't need to install ghostscript anymore with the latest version (1.2.0) of the plugin - thanks to a wonderful pullrequest.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 24, 2017 @ 10:52
    Laurens Gregoir
    0

    So only the DLL's are required then? I'll update the plugin :)

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 24, 2017 @ 13:12
    Damiaan
    1

    Yes indeed. You don't need to install ghostscript anymore.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 26, 2017 @ 08:27
    Laurens Gregoir
    0

    Perfect, can confirm that it is working on my old dev environment that doesn't allow you to install ghostscript on the virtual server.

    Also at the moment I do not see the error reocurring about the ghostscript.net API call exception: Ghostscript.NET.GhostscriptAPICallException: An error occured when call to 'gsapinewinstance' is made: -100

    But probably because it isn't used anymore?

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 26, 2017 @ 08:30
    Damiaan
    1

    It feels more like he is now able to call it, and previously it was not.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 26, 2017 @ 08:39
    Laurens Gregoir
    0

    Then I retract my previous statement :)

    Final question, will you create an Umbraco package as well, besides the nuget & github packages?

  • Damiaan 380 posts 1044 karma points c-trib
    Apr 26, 2017 @ 08:46
    Damiaan
    1

    Good remark! I really should. :-D

    I'll see what I can do today.

  • Laurens Gregoir 134 posts 566 karma points
    Apr 26, 2017 @ 08:53
    Laurens Gregoir
    0

    I'll happely test it :)

    Then you can contain in it all pre-reqs for the plugin :)

Please Sign in or register to post replies

Write your reply to:

Draft