Jump to content
horst

Croppable Image 3

Recommended Posts

3 hours ago, horst said:

@PWaddict

I may seem a little impatient now, but I still don't understand what you want after all your posts. Please just write down 2 or three variation names where I can see what is and what should be. Otherwise I cannot deal with it any further. (I have three deadlines this week!)

Ok on the Crop Settings of a "Croppable Image 3" field I have "thumbnail,1200,600" so when I upload an image to that field I'm getting the following files inside site/assets/files folder:

myimage.jpg (original)
myimage.0x260.jpg (original variation)

myimage.-thumbnail.jpg (crop)
myimage.-thumbnail.0x48n.jpg (crop variation)

All I want is the cropped images with the ".-thumbnail" to include a timestamp of their modification time (mtime) so the site/assets/files folder should contain ONLY the following files:

myimage.jpg (original)
myimage.0x260.jpg (original variation)

myimage.-thumbnail-1543078585.jpg (crop)
myimage.-thumbnail-1543078585.0x48n.jpg (crop variation)

Everytime the crop is modified the timestamp on the filename should renamed with the new one.

I hope you understand now.

Share this post


Link to post
Share on other sites

If you want to cache-busting the image, you may add the following to ready.php

$wire->addHookAfter('Pagefile::url', 'addTimeStamp');
$wire->addHookAfter('Pagefile::httpUrl', 'addTimeStamp');

function addTimeStamp($event){
	if($event->page->template == 'admin') return;

	$modified = $event->object->modified;
	$event->return = $event->return . "?v=$modified";

}

 

Share this post


Link to post
Share on other sites
56 minutes ago, Karl_T said:

If you want to cache-busting the image, you may add the following to ready.php

Query strings are no longer work on Facebook. Page url or filename must be renamed in order for Facebook to fetch the new image.

Share this post


Link to post
Share on other sites

@horst problem solved on renaming images by using "Custom Upload Names" module which does really good job with timestamps and also giving automatically better names in general.

Now about "Croppable Image 3" module today I noticed a "hidden" error on the cropping page if you have debug mode on and the image is inside repeater:

Quote

Notice: Only variables should be passed by reference in C:\xampp\htdocs\mysite\site\modules\CroppableImage3\ProcessCroppableImage3\ProcessCroppableImage3.module on line 67

Here is the screenshot with the "hidden" error:

issue.thumb.jpg.de2bd63ade54c0dcc48874f7d18f1b4d.jpg

  • Like 1

Share this post


Link to post
Share on other sites

@PWaddict

Good to hear that you solved together with adrian the timestamp issue, and thanks for reporting the Notice.
Please can you try if the following code solves it?
 

// replace the old lines 66 - 69 with this lines:
66        if(preg_match("/_repeater[0-9]+$/", $field)) {
67            $explodeArray = explode("_repeater", $field); 
68            $pages_id = intval(end($explodeArray));
69            $field = str_replace("_repeater{$pages_id}", '', $field);
70        } else {

 

Share this post


Link to post
Share on other sites
2 hours ago, horst said:

@PWaddict

Good to hear that you solved together with adrian the timestamp issue, and thanks for reporting the Notice.
Please can you try if the following code solves it?
 


// replace the old lines 66 - 69 with this lines:
66        if(preg_match("/_repeater[0-9]+$/", $field)) {
67            $explodeArray = explode("_repeater", $field); 
68            $pages_id = intval(end($explodeArray));
69            $field = str_replace("_repeater{$pages_id}", '', $field);
70        } else {

 

I'm getting "The process returned no content." with the error:

Quote

Notice: Undefined variable: fieldName in C:\xampp\htdocs\mysite\site\modules\CroppableImage3\ProcessCroppableImage3\ProcessCroppableImage3.module on line 99

 

  • Like 1

Share this post


Link to post
Share on other sites

Ok thanks for trying. It was a shot into the blue. I will setup a repeater field locally and debug it. (Maybe tomorrow) 

  • Like 1

Share this post


Link to post
Share on other sites

Hello, 

I have problem with this plugin. I did every step in intro (new filed with Croppable3, field assigned to template project, 4 crop settings with no template restrictions). When I try it on frontend I got

"Exception: There is no crop setting for the template 'project' called 'portrait'"

When I debug $inputFieldInstance->cropSetting on 202line of plugin, I got NULL. What is more interesting, in admin section debug outputs right settings (landscape,900,600 portrait .. etc). I am really desperate, maybe I am missing something? 

ProcessWire 3.0.62 - it's existing project..

I will grateful for any help! Thanks in advance 🙂

Share this post


Link to post
Share on other sites

Have you done a quick test with adding the templatename to the portrait-cropsetting? Does this behave different?

portrait,300,500,project

?

Share this post


Link to post
Share on other sites

I installed Croppable Image 3 yesterday and am currently trying to configure and install it in the template.

I have just on the page where directly the images are deposited this message.

Fatal error: Uncaught Error: Call to a member function getCrop() on boolean in /home/frawanbd/estate.frawal.net/site/templates/_main.php:92 Stack trace: #0 /home/frawanbd/estate.frawal.net/wire/core/TemplateFile.php(297): require() #1 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render() #2 /home/frawanbd/estate.frawal.net/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___render', Array) #3 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array) #4 /home/frawanbd/estate.frawal.net/wire/modules/PageRender.module(514): ProcessWire\Wire->__call('render', Array) #5 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(383): ProcessWire\PageRender->___renderPage(Object(ProcessWire\HookEvent)) #6 /home/frawanbd/estate.frawal.net/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___renderPage', Array) #7 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(442): ProcessWire\WireHook in /home/frawanbd/estate.frawal.net/site/templates/_main.php on line 92

Schwerwiegender Fehler: Uncaught Error: Call to a member function getCrop() on boolean in /home/frawanbd/estate.frawal.net/site/templates/_main.php:92
Stack trace:
#0 /home/frawanbd/estate.frawal.net/wire/core/TemplateFile.php(297): require()
#1 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render()
#2 /home/frawanbd/estate.frawal.net/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___render', Array)
#3 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array)
#4 /home/frawanbd/estate.frawal.net/wire/modules/PageRender.module(514): ProcessWire\Wire->__call('render', Array)
#5 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(383): ProcessWire\PageRender->___renderPage(Object(ProcessWire\HookEvent))
#6 /home/frawanbd/estate.frawal.net/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___renderPage', Array)
#7 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(442): ProcessWire\WireHook (Zeile 92 in /home/frawanbd/estate.frawal.net/site/templates/_main.php)

Diese Fehlermeldung wurde angezeigt wegen: Site ist im Debug-Modus. ($config->debug = true; => /site/config.php). Fehler wurde protokolliert.

On the start page I tried to install the pictures and there comes this message

Fehler: Exception: There is no crop setting for the template 'home' called 'square' (in /home/frawanbd/estate.frawal.net/site/modules/CroppableImage3/FieldtypeCroppableImage3/FieldtypeCroppableImage3.module line 209)

#0 /home/frawanbd/estate.frawal.net/wire/core/WireHooks.php(822): ProcessWire\FieldtypeCroppableImage3->getCrop(Object(ProcessWire\HookEvent))
#1 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Pageimage), 'getCrop', Array)
#2 /home/frawanbd/estate.frawal.net/site/templates/_main.php(92): ProcessWire\Wire->__call('getCrop', Array)
#3 /home/frawanbd/estate.frawal.net/wire/core/TemplateFile.php(297): require('/home/frawanbd/...')
#4 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render()
#5 /home/frawanbd/estate.frawal.net/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___render', Array)
#6 /home/frawanbd/estate.frawal.net/wire/core/Wire.php(442): ProcessWire\WireHooks->ru

Diese Fehlermeldung wurde angezeigt wegen: Site ist im Debug-Modus. ($config->debug = true; => /site/config.php). Fehler wurde protokolliert.

I currently have only one _main.php and I have taken the code from EXAMPLE there.

 

					<div class="gallery">
						<?php
							// get the first image instance of crop setting 'portrait'
							$image = $page->images->first()->getCrop('square');
							echo "<img src='{$image->url}' alt='{$image->description}' />";
						?>
					</div>

Config from Fieldtype:
image.png.e49efb23694a7a81041600ce190fcaf2.png

Share this post


Link to post
Share on other sites
3 hours ago, csaeum said:

Call to a member function getCrop() on boolean

in

3 hours ago, csaeum said:

/site/templates/_main.php:92

Here you call it on a var that is not a pageimage but a boolean! First check if you REALLY have an image, before you call ->getCrop() on it.

 

And which PW version and module version you are using?

Share this post


Link to post
Share on other sites

ProcessWire Core (Master)     ProcessWire master     3.0.123
Croppable Image 3 (Wrapper-Module)     CroppableImage3     1.1.16

Ok my mistake is solved.

My CPI3 Field was gallery and not images, this was the standard field in the PW demo

 

  • Like 1

Share this post


Link to post
Share on other sites

@horst, as mentioned here, it looks like your module is not compatible with the new WebP support added in 3.0.132. Or am I doing it wrong?

Share this post


Link to post
Share on other sites

When I try it, I get something like: 

Notice: Undefined index: _width in \wire\core\Pageimage.php on line 1936

Notice: Undefined index: _height in \wire\core\Pageimage.php on line 1937

These are the new additions from Ryan that I'm currently have not checked how it works, but definetly, if width and height isn't known, the engines cannot create a new variation.
I get this for image objects derived from CAI3 and with the original image too!

Possibly a bug in the new pageimage additions, or a different use case that currently is not covered.

  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)

Here is a first try with webp support: github webp-dev

!! ATTENTION: DO NOT USE ON PRODUCTION SITES !!

Maybe the cleaning up for unused variations is broken now. Haven't tested!

Also the naming scheme of CAI3->getCrop("suffix") has changed from 
    basename.-suffix.ext
to 
    basename.{width}x{height}-suffix.ext

Would be fine if some of you have time to test and report back in regard of:

  • removing no longer used variations,
  • changing values of already defined crop settings, (and if previously used variations get deleted, etc)
  • ...

Currently there has to be defined true in site/config.php for $config->imageSizerOptions("webpAdd", true);

Then you can use it like with core images:

    $image = $page->images->first->getCrop("suffix");
    echo "<img src='{$image->url}' /> <img src='{$image->webp->url}' />";

 

Edited by horst

Share this post


Link to post
Share on other sites

Hi!

I have an issue when I upload an image into the field. This is one of the log messages ("matalampi" is the crop setting😞

/../site/assets/files/1328/testiimagenodashes-1.-matalampi.0x48.jpg
- Unable to copy /../site/assets/files/1328/testiimagenodashes-1.-matalampi.jpg
=> /../site/assets/cache/WireTempDir/.PFM0.06231100T1568804893RIbnRkmpEmZApFan/0/testiimagenodashes-1.-matalampi.0x48.jpg

Same error comes from all variations.

Apparently the field tries to create file variations from the image immediately after upload, but for some reason it doesn't work and a corrupted file is created. This becomes a problem when I try to check if there exists a cropped version of the image: It thinks that there is one, but since it's corrupted, image doesn't show in site.

Is there a way to prevent variations being created before user actually crops the image?

var_dump of image, if it helps anything ("matalampi", "korkeampi" and "normaali" are crop settings😞

object(ProcessWire\Pageimage)#370 (13) {
	["url"]=> string(71) "/../site/assets/files/1448/img.-normaali.jpg"
	["filename"]=> string(100) "/../site/assets/files/1448/img.-normaali.jpg"
	["filesize"]=> bool(false)
	["description"]=> string(0) ""
	["tags"]=> string(0) ""
	["created"]=> string(18) "17.9.2019 14:09:57"
	["modified"]=> string(18) "17.9.2019 14:09:57"
	["filemtime"]=> string(17) "1.1.1970 02:00:00"
	["width"]=> int(0)
	["height"]=> int(0)
	["suffix"]=> string(0) ""
	["original"]=> string(34) "img.jpg"
	["variations"]=> array(5) { 
		[0]=> string(40) "img.0x260.jpg"
		[1]=> string(50) "img.-matalampi.0x48.jpg"
		[2]=> string(50) "img.-korkeampi.0x48.jpg"
		[3]=> string(50) "img.-normaali.670x0.jpg"
		[4]=> string(49) "img.-normaali.0x48.jpg" 
	}
}

"filemtime" looks kinda fishy: Does it affect anything?

Edit: Aaand as soon as I decided to ask this, it seems that the issue was that my crop setting names had capital letters! So heads up for that to others as well 😄

  • Like 2

Share this post


Link to post
Share on other sites
7 hours ago, iipa said:

Edit: Aaand as soon as I decided to ask this, it seems that the issue was that my crop setting names had capital letters! So heads up for that to others as well 😄

Hi @iipa, after (re)naming the cropsettings lowercase [a-z0-9], the issue is gone, or not?

Share this post


Link to post
Share on other sites
On 9/18/2019 at 9:52 PM, horst said:

Hi @iipa, after (re)naming the cropsettings lowercase [a-z0-9], the issue is gone, or not?

Yes, issue is gone now 🙂

  • Like 1

Share this post


Link to post
Share on other sites

Couple of other questions though:

1. If I have multiple cropping options (normal, higher, lower height), how can I easily control which crop setting should be used? Since it does all crops when uploading the image, I can't simply check if a crop version exists. Also what if I want to use the original image instead of crop versions, how can I select that?

2. Translation file lacks a few fields from the modal: "ESC" and cropped image parameters (imgUrl, suffix, width x height, quality, sharpening). Also cropped image modal title "Save" can't be translated.

Otherwise great module! 🙂

 

 

  • Like 1

Share this post


Link to post
Share on other sites
9 hours ago, iipa said:

If I have multiple cropping options (normal, higher, lower height), how can I easily control which crop setting should be used? Since it does all crops when uploading the image, I can't simply check if a crop version exists.

I don't understand what's the question means ?? When you upload an image to a field with 3 defined crop settings, there will be created 3 default crops. So there ever is a crop present, but not a manually user defined one. ??

 

9 hours ago, iipa said:

Also what if I want to use the original image instead of crop versions, how can I select that?

You can do everything with it what you can do with the regular pw core imagefield. (The CropabbleImge is an extended PW core imagefield)

$image->url;
$image->width(500)->url;
$image->size(300, 400, ['sharpening' => 'medium', 'quality' => 85])->url;

 

9 hours ago, iipa said:

Translation file lacks a few fields from the modal: "ESC" and cropped image parameters (imgUrl, suffix, width x height, quality, sharpening). Also cropped image modal title "Save" can't be translated.

Thanks for pointing me to this!

Share this post


Link to post
Share on other sites
10 hours ago, horst said:

I don't understand what's the question means ?? When you upload an image to a field with 3 defined crop settings, there will be created 3 default crops. So there ever is a crop present, but not a manually user defined one. ??

Yes, there will always be default crops. Problem is that I don't need to use all of them, just one.

I'll try to explain better:

1. User uploads an image.
2. If user thinks the image is good as it is, render the uncropped version.
3. If user wants to crop the image, user selects which crop setting they want to use, and then render that crop version.

Problem is how can I detect which version should I use? I can't check if a version exists, since they always do.

Share this post


Link to post
Share on other sites
7 hours ago, iipa said:

Yes, there will always be default crops. Problem is that I don't need to use all of them, just one.

I'll try to explain better:

1. User uploads an image.
2. If user thinks the image is good as it is, render the uncropped version.
3. If user wants to crop the image, user selects which crop setting they want to use, and then render that crop version.

Problem is how can I detect which version should I use? I can't check if a version exists, since they always do.

Ah ok. There is no build in solution for this. You have to build something yourself. For example, if there is currently no use of tags, (or an expandable usage of tags), with this imagefield, you may setup tags with predefined values, so that the user can select one if he like to. If this is not possible due to restricted other usage of tags, it may become very uncomfortable, as there are currently no other fields bundled together with an image (besides description and tags). I'm not sure if the imageextra module from justb3a is uptodate with the current devstate (?), If so, and if tags are no option, this would be the way to go.

  • Thanks 1

Share this post


Link to post
Share on other sites
On 9/24/2019 at 7:38 PM, horst said:

Ah ok. There is no build in solution for this. You have to build something yourself. For example, if there is currently no use of tags, (or an expandable usage of tags), with this imagefield, you may setup tags with predefined values, so that the user can select one if he like to. If this is not possible due to restricted other usage of tags, it may become very uncomfortable, as there are currently no other fields bundled together with an image (besides description and tags). I'm not sure if the imageextra module from justb3a is uptodate with the current devstate (?), If so, and if tags are no option, this would be the way to go.

Actually I came to a pretty handy solution with my co-dev! Images have information about their modification time saved within them, so using that I came up with following code:

$img = $page->image;

// check if image exists
if($img) {
	// fetch cropped images' modification timestamps
  	$tsNormal = filemtime($img->getCrop('normaali')->filename);
  	$tsHigh = filemtime($img->getCrop('korkeampi')->filename);
  	$tsLow = filemtime($img->getCrop('matalampi')->filename);
  	// check if they have the same modification time => user hasn't cropped the image, so use the original
	if(!($tsNormal == $tsHigh && $tsNormal == $tsLow)) {
		// stamps are not equal => check which is highest aka last modified
  		switch(max($tsNormal, $tsHigh, $tsLow)) {
  			case $tsNormal:
  				$img = $img->getCrop('normaali');
  				break;
  			case $tsHigh:
  				$img = $img->getCrop('korkeampi');
  				break;
  			case $tsLow:
  				$img = $img->getCrop('matalampi');
  				break;
  		}
  	} 
}

Seems to work quite nicely for my purpose 🙂Thought it would be nice to share, if anybody else wants to achieve similar effect!

  • Like 4
  • Thanks 1

Share this post


Link to post
Share on other sites

After updating PW 3 to 1.4.1 today (PHP 7.3) I got fatal errors and had to rollback.

Compile Error:
Cannot make non static method ProcessWire\FieldtypeFile::getModuleConfigInputfields() static in class ProcessWire\FieldtypeCroppableImage3 (line 4 of //site/modules/CroppableImage3/FieldtypeCroppableImage3/FieldtypeCroppableImage3.module)

Anyone else with this problem?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By gebeer
      I am happy to present my new fieldtype FieldtypeImageFromPage. It is made up of 2 modules:
      Fieldtype Image Reference From Another Page is a Fieldtype that stores a reference to a single image from another page. The image can be selected with the associated Inputfield.
      Inputfield Select Image From Page is an Inputfield to select a single image from images on a predefined page and it's children.
      And there also is a helper module that takes care of cleanup tasks.
      This module evolved out of a discussion about my other Module FieldtypeImagePicker.  It caters for use cases where a set of images is being reused multiple times across a site. With this fieldtype these images can be administered through a chosen page. All images uploaded to that page will be available in the inputfield.
      When to use ?
      Let editors choose an image from a set of images that is being used site-wide. Ideal for images that are being re-used across the site.
      Suited for images that are used on multiple pages throughout the site (e.g. icons).
      Other than the native ProcessWire images field, the images here are not stored per page. Only references to images on another page are stored. This has several advantages:
      one central place to organize images when images change, you only have to update them in one place. All references will be updated, too. (Provided the name of the image that has changed stays the same) Features
      Images can be manipulated like native ProcessWire images (resizing, cropping etc.) Image names are fully searchable through the API Accidental image deletion is prevented. When you want to delete an image from one of the pages that hold your site-wide images, the module searches all pages that use that image. If any page contains a reference to the image you are trying to delete, deletion will be prevented. You will get an error message to help you edit those pages and remove references there before you can finally delete the image. How to install and setup
      Download and install this module like any other modules in ProcessWire Create a page in the page tree that will hold your images. This page's template must have an images field Upload some images to the page you created in step 2 Create a new field. As type choose 'Image Reference From Another Page'. Save the field. In 'Details' Tab of the field choose the page you created in step 2 Click Save button Choose the images field name for the field that holds your images (on page template from step 2) Click Save button again Choose whether you want to include child pages of page from step 2 to supply images Add the field to any template You are now ready to use the field View of the inputfield on the page edit screen:

      View of the field settings

      The module can be installed from this github repo. Some more info in the README there, too.
      In my tests it was fairly stable. After receiving your valued feedback, I will eventually add it to the modules directory.
      My ideas for further improvement:
      - add ajax loading of thumbnails
      Happy to hear your feedback!
       
    • By gebeer
      Although the PW backend is really intuitive, ever so often my clients need some assistance. Be it they are not so tech savvy or they are not working in the backend often.
      For those cases it is nice to make some help videos available to editors. This is what this module does.
      ProcessHelpVideos Module
      A Process module to display help videos for the ProcessWire CMS. It can be used to make help videos (screencasts) available to content editors.
      This module adds a 'Help Videos" section to the ProcessWire backend. The help videos are accessible through an automatically created page in the Admin page tree. You can add your help videos as pages in the page tree. The module adds a hidden page to the page tree that acts as parent page for the help video pages. All necessary fields and templates will be installed automatically. If there are already a CKEditor field and/or a file field for mp4 files installed in the system, the module will use those. Otherwise it will create the necessary fields. Also the necessary templates for the parent help videos page and it's children are created on module install. The module installs a permission process-helpvideos. Every user role that should have access to the help video section, needs this permission. I use the help video approach on quite a few production sites. It is stable so far and well received by site owners/editors. Up until now I installed required fields, templates and pages manually and then added the module. Now I added all this logic to the install method of the module and it should be ready to share.
      The module and further description on how to use it is available on github: https://github.com/gebeer/ProcessHelpVideos
      If you like to give it a try, I am happy to receive your comments/suggestions here.
    • By Robin S
      A module created in response to the topic here:
      Page List Select Multiple Quickly
      Modifies PageListSelectMultiple to allow you to select multiple pages without the tree closing every time you select a page.
      The screencast says it all:

       
      https://github.com/Toutouwai/PageListSelectMultipleQuickly
      https://modules.processwire.com/modules/page-list-select-multiple-quickly/
    • By gebeer
      Hello all,
      sharing my new module FieldtypeImagePicker. It provides a configurable input field for choosing any type of image from a predefined folder.
      The need for it came up because a client had a custom SVG icon set and I wanted the editors to be able to choose an icon in the page editor.
      It can also be used to offer a choice of images that are used site-wide without having to upload them to individual pages.
      There are no image manipulation methods like with the native PW image field.
      Module and full description can be found on github https://github.com/gebeer/FieldtypeImagePicker
      Kudos to @Martijn Geerts. I used his module FieldTypeSelectFile as a base to build upon.
      Here's how the input field looks like in the page editor:

      Hope it can be of use to someone.
      If you like to give it a try, I'm happy to hear your comments or suggestions for improvement. Eventually this will go in the module directory soon, too.
    • By bernhard
      @Sergio asked about the pdf creation process in the showcase thread about my 360° feedback/survey tool and so I went ahead and set my little pdf helper module to public.
      Description from PW Weekly:
       
      Modules Directory: https://modules.processwire.com/modules/rock-pdf/
      Download & Docs: https://github.com/BernhardBaumrock/RockPDF
       
      You can combine it easily with RockReplacer: 
      See also a little showcase of the RockPdf module in this thread:
       
×
×
  • Create New...