Jump to content

Admin hook, image upload, watermark, PIM


Hardoman
 Share

Recommended Posts

Hello community,

we have a website running version 3.0.118. The owner would like to have a watermark merged to the images, that are being uploaded in the CKEditor as a requirement.
Image upload besides the CKEditor within galleries and single images works as a charm already. We also use croppable image 3 there. (PIM2)

To realize this requirement, I thought of using a hook in the admin area. So, I read a lot in our forums and tested this by adding a hook into the ready.php file.

$this->addHookAfter('InputfieldFile::fileAdded',function(HookEvent$event){
wire('log')->save('test','Image upload works');
...

The log entry is being created correctly. But when I try to use the pim/watermark-function like in a template, he cannot find the watermark-image anymore. Furthermore, when I try to get the page-id, it does not seem to be accessible, because the application does not seem to know how to reference it, or I dont know the right way to do so…

So my questions are:
 

  • Is this the right attempt at all or will there be another, better workaround?
  • It seems, I cannot access the page object (of the content page) within this scope or file but I would need it to save the processed image inside the right files/id folder
  • Would it be better to place the hook into the admin-template? (or admin.php)
     

Thanks for any hints in advance. ?

Link to comment
Share on other sites

15 minutes ago, Hardoman said:

But when I try to use the pim/watermark-function like in a template, he cannot find the watermark-image anymore.

How do you try to get this image?

15 minutes ago, Hardoman said:

Would it be better to place the hook into the admin-template? (or admin.php)

Doesn't really matter ? 

  • Like 1
Link to comment
Share on other sites

5 hours ago, Hardoman said:

So my questions are:
 

  • Is this the right attempt at all or will there be another, better workaround?
  • It seems, I cannot access the page object (of the content page) within this scope or file but I would need it to save the processed image inside the right files/id folder
  • Would it be better to place the hook into the admin-template? (or admin.php)

Hi @Hardoman

I post you a code example below that works for me since ages and also with recent PW versions. It includes watermarking too!

It is called in a custom module and the event is >before "InputfieldFile::fileAdded" <, but you can call it in ready.php too.

Hopefully it is of help for you. Otherwise please ask further. :)

    public function importImage($event) {

        $inputfield = $event->object;                      // handle to the image field
        if(!$inputfield instanceof InputfieldImage) {      // we need an images field, not a file field
            return;                                        // early return
        }

        if(version_compare(wire('config')->version, '2.8.0', '<')) {
            $p = $inputfield->value['page'];               // get the page, PW < 2.8
        } else {
            $p = $inputfield->attributes['value']->page;   // get the page, PW >= 2.8 | 3.0 (or only from 3.0.17+ ??)
        }

        if('images' != $inputfield->name) return;          // we assume a field with name: images
        if('album' != $p->template) return;                // don't do it on other pages than archive album

        $image = $event->argumentsByName('pagefile');      // get the image



        // prebuild variations
            // AdminThumb
            $image->height(260);

            // AlbumThumbnail
            $portrait = $image->height > $image->width;
            $w = 228;
            if($portrait) {
                $w1 = intval($w);
                $h1 = intval(($w1 / 3 * 4) + 38);
            } else {
                $w1 = intval($w);
                $h1 = intval(($w1 / 3 * 2));
            }
            $image->crop("width=$w1, height=$h1");

            // Slick-Slideshow
            $wmPng = $this->pages->get('id=13967')->getUnformatted('watermark')->first()->width(403);
            // sharpening added, quality from 80 to 90
                $master = $image->contain('width=1000, height=700, quality=100, sharpening=none');
                $master = $master->pim2Load('full', false)->watermarkLogo($wmPng)->setQuality(100)->setUpscaling(true)->setSharpening('none')->pimSave();
                $sizeArray = array(array(448, 336), array(678, 506), array(908, 676));
                foreach($sizeArray as $sizes) {
                    $master->size($sizes[0], $sizes[1], array('upscaling'=>false, 'cropping'=>false, 'quality'=>90, 'sharpening'=>'soft'));
                }
            // sharpening added, quality from 80 to 90
        // prebuild variations



        // check / import IPTC data
            $additionalInfo = array();
            $info = @getimagesize($image->filename, $additionalInfo);
            if($info !== false && is_array($additionalInfo) && isset($additionalInfo['APP13'])) {
                $iptc = iptcparse($additionalInfo["APP13"]);
                if(is_array($iptc) && isset($iptc["2#025"]) && is_array($iptc["2#025"]) && count($iptc["2#025"])>0) {
                    $tmp = $iptc["2#025"];
                    $tags = array();
                    foreach($tmp as $k=>$v) {
                        if(empty($v)) continue;
                        $tags[] = jhpTextConversion(trim(strtolower($v)));
                    }
                    $p->images->trackChange('tags');               // prepare page to keep track for changes
                    $image->tags = implode(', ', $tags);
                    $p->save('images');                            // save the page
                }
            }
        // check / import IPTC data

    }

 

  • Like 5
Link to comment
Share on other sites

Hello Horst,

thanks again for your hints, the following solution works for me, replaces the original image and the merged image is usable in the editor afterwards:

(Code is embedded in ready.php)

$this->addHookBefore("InputfieldImage::fileAdded", function ($event) {

    // Get the image
    $image = $event->argumentsByName('pagefile');

    // Location of watermark image
    $pngAlphaImage = $config->paths->templates . 'watermark.png';

    //Save image with watermark
    $master = $image->pim2Load('full', false)->watermarkLogo($pngAlphaImage,'SE', 0)->pimSave();

    //Setting some variations
    $sizeArray = array(array(448, 336), array(678, 506), array(908, 676));

    foreach($sizeArray as $sizes) {
        $master->size($sizes[0], $sizes[1], array('upscaling'=>false, 'cropping'=>false, 'quality'=>90, 'sharpening'=>'soft'));
    }

    $image->setFilename($master);
    //Set generated image as main image
    $image->setOriginal($master);

});

 

  • Like 1
Link to comment
Share on other sites

  • Hardoman changed the title to [solved] Admin hook, image upload, watermark, PIM
  • 2 weeks later...

Unfortunately, I have to re-open this topic once more. When we implement the function above, the pim-created image is saved as a variation along with the original image. If you now embed the watermark image and somebody removes the original image, all the variations are gone, so the pim-image will vanish as well and furthermore the user will get a warning.

I did not find out yet, where I can avoid the new image to be deleted when the original one is being deleted. 

 

So would there be a way to duplicate the watermark image that it would be treated like a separate orignal one? Probably by cloning the pagefile object or something like this?

Any help would be highly appreciated. Thank you.

Link to comment
Share on other sites

@Hardoman If I understand correct, you want to watermark the original image. Is this right?

If so, you may want to watermark the original image directly. This way you don't need to delete the original image and copy / move around the watermarked variation.

If you look into the PIM docs, you will find a description how to work on system files instead of Pageimage objects. This would be the way to go.

 

Quote

* (how) can I use the ImageManipulator with other imagefiles than PW-Pageimages?

You can load any imagefile from your servers filesystem into the ImageManipulator with:


$pim = wire('modules')->get('PageImageManipulator')->imLoad($imageFilename);
// or
$pim = $wire->modules->get('PageImageManipulator')->imLoad($imageFilename, $options);

You can directly with the imLoad-method pass specific $options or you can do a separate call to setOptions(). Then you do your desired actions and last but not least you call save()! Most time I think the original passed file gets overwritten with the manipulation result, but you are also able to save to a different name and  / or fileformat. If so, it is useful to get the final (sanitized) filename back after saveing.


$optionalNewFilename = $pim->setOptions($options)->height(360)->flip()->blur()->save();

Also you may call this in one line if you prefer:


if(false!==$wire->modules->get('PageImageManipulator')->imLoad($imageFilename,$options)->height(360)->flip()->blur()->save()) {
    // success !!
}

-------------------------------------------------------------------

see this post, the 3 tip: https://processwire.com/talk/topic/4264-page-image-manipulator-1/?tab=comments#comment-41748

 

Link to comment
Share on other sites

@horst Thanks for your quick reply! ?

Quote

If I understand correct, you want to watermark the original image. Is this right?

We would like to offer both types original and watermarked image. So that the user would be able to choose between them and post them in the editor. This already works now but not after somebody deletes the original image from the array.

We already tried to clone the object but there still is some link the the variations and also in the cloned object, the variations disappear. Probably in this case its not good to put the hook into the ready.php file.

Link to comment
Share on other sites

@horst Little update, this might be helpful for explanation:

we quickly tested editing the PIM02.module file (around line 122) and that seems to work for our demand:

$suffix = str_replace('-', '', $prefix);
        $suffix = "{$suffix}";
//        $suffix = "pim2-{$suffix}";
        if (false === strpos($p['filename'], '.')) $suffix = '.' . $suffix;

After this modification the watermark image is still there and it would work, unless somebody would like to delete all the variations the common way.

?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...