Perhaps it could be a good idea to add TinyPNG service to pipelines. I also commented (#2819895-6: Drupal 8 Version) this on the D8 port ticket in TinyPNG module .

Comments

IT-Cru created an issue. See original summary.

it-cru’s picture

Issue summary: View changes
it-cru’s picture

Add TinyPNG pipeline processor and requirement of tinify PHP library into composer.json. Definition of Tinify service is missing yet.

it-cru’s picture

Status: Active » Needs review
it-cru’s picture

Switch to buffer handling to get TinyPNG pipeline working correct.

adrian83’s picture

I like this idea! Tiny PNG is great, especially for PNG images. But I found out that if I compress the source PNG on tinypng.com, then use Drupal's default image styles to "compress" the output, Drupal will make the PNG large again.

adrian83’s picture

OK, I tried this patch. When I try to edit an image style that has "Sitewide default pipeline: TinyPNG" on it, I get a white screen error and this error in the error log:

Error: Call to undefined function Tinify\setKey() in Drupal\imageapi_optimize\Plugin\ImageAPIOptimizeProcessor\TinyPng->applyToImage() (line 60 of /home/tractors/public_html/mm/web/modules/contrib/imageapi_optimize/src/Plugin/ImageAPIOptimizeProcessor/TinyPng.php) #0 /home/tractors/public_html/mm/web/modules/contrib/imageapi_optimize/src/Entity/ImageAPIOptimizePipeline.php(178): Drupal\imageapi_optimize\Plugin\ImageAPIOptimizeProcessor\TinyPng->applyToImage('public://styles...') #1 /home/tractors/public_html/mm/web/modules/contrib/imageapi_optimize/src/Entity/ImageStyleWithPipeline.php(21): Drupal\imageapi_optimize\Entity\ImageAPIOptimizePipeline->applyToImage('public://styles...') #2 /home/tractors/public_html/mm/web/core/modules/image/image.admin.inc(54): Drupal\imageapi_optimize\Entity\ImageStyleWithPipeline->createDerivative('core/modules/im...', 'public://styles...') #3 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Theme/ThemeManager.php(287): template_preprocess_image_style_preview(Array, 'image_style_pre...', Array) #4 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Render/Renderer.php(435): Drupal\Core\Theme\ThemeManager->render('image_style_pre...', Array) #5 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Render/Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #6 /home/tractors/public_html/mm/web/core/includes/common.inc(870): Drupal\Core\Render\Renderer->render(Array, false) #7 /home/tractors/public_html/mm/web/core/modules/image/src/Form/ImageStyleEditForm.php(61): drupal_render(Array) #8 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Entity/EntityForm.php(115): Drupal\image\Form\ImageStyleEditForm->form(Array, Object(Drupal\Core\Form\FormState)) #9 [internal function]: Drupal\Core\Entity\EntityForm->buildForm(Array, Object(Drupal\Core\Form\FormState)) #10 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Form/FormBuilder.php(514): call_user_func_array(Array, Array) #11 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Form/FormBuilder.php(271): Drupal\Core\Form\FormBuilder->retrieveForm('image_style_edi...', Object(Drupal\Core\Form\FormState)) #12 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Controller/FormController.php(74): Drupal\Core\Form\FormBuilder->buildForm('image_style_edi...', Object(Drupal\Core\Form\FormState)) #13 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch)) #14 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #15 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #16 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #17 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #18 [internal function]: Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #19 /home/tractors/public_html/mm/vendor/symfony/http-kernel/HttpKernel.php(144): call_user_func_array(Object(Closure), Array) #20 /home/tractors/public_html/mm/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #21 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #22 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23 /home/tractors/public_html/mm/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24 /home/tractors/public_html/mm/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #27 /home/tractors/public_html/mm/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #28 /home/tractors/public_html/mm/web/core/lib/Drupal/Core/DrupalKernel.php(656): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #29 /home/tractors/public_html/mm/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #30 {main}.

it-cru’s picture

@Adrian83: You have to do a composer require tinify/tinify in your project. This is included in the patch of composer.json file as requirement, but it depends on your workflow how this is found by composer after patching.

adrian83’s picture

@IT-Cru Yes, that possibility dawned on me overnight, and I did a composer require tinify/tinify in my project. That took care of the errors. Thank you for your quick response!

My TinyPNG dashboard now shows that I have compressed a number of photos. I cleared cache, but so far my page size is the same. The images I save off the page are still the original size; if I compress them on TinyPNG's site, they will still shrink quite a bit. I wonder If there is another cache that needs to be cleared?

Or maybe TinyPNG isn't happening last? I have found that if I upload a PNG compressed by TinyPNG, Drupal's default resizing engine will blow those PNGs back up again and make them larger.

it-cru’s picture

@Adrian83: Do you have done a drush image-flush? Perhaps there are existing images in image styles folders which are not compressed yet by TinyPNG.

But perhaps TinyPNG API communication isn't working correctly with my patch.

adrian83’s picture

@IT-Cru Yes, that is what I missed. I was assuming that clearing all caches would clear image styles, but evidently not. Now that I cleared out the image styles, TinyPNG seems to be doing its job.

At this point, everything I reported was user education, not a bug in the patch. I vote for moving this patch into the module. The service is free only up to 500 compressions / month, which will get used up rapidly if you are using a lot of responsive images. However, because TinyPNG can in some cases dramatically reduce image size, especially with PNGs, but sometimes also with JPGs, many users could see it worth the money. I have reduced the weight of my image-heavy home page by 900 KB by using TinyPNG.

steven jones’s picture

Status: Needs review » Reviewed & tested by the community

This is cool!

Thanks so much for the patch and the review.

I do wonder if we can do better and inject the TinyPNG class into our plugin as a service, but we can do that sort of stuff in a follow up I think.
Lets get this in while we're in beta, and cleanups can come later.

  • Steven Jones committed a226380 on 8.x-2.x authored by IT-Cru
    Issue #2854874 by IT-Cru, Adrian83: Add support for TinyPNG / TinyJPEG...
steven jones’s picture

Status: Reviewed & tested by the community » Fixed
adrian83’s picture

I'm happy to see this patch committed to the module! I now expect to be adding the Image Optimize module to more of my sites.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.