craft-imageoptimize
craft-imageoptimize copied to clipboard
[FR] Request for watermark support
Coming in with a feature request per request from #craftcms on slack (I'm apparently the second person today that wants this functionality). Thanks!
Sounds good! I've posted an Article on medium how we use watermarks or sharing images with logos. https://medium.com/webdevs/craft-cms-create-custom-share-images-with-your-company-logo-cb09d9ccb700
We create our Share Images and add a logo within it:

And here is another example:
I merge two Images. This inside the Screen is the "Watermark"

Options requests
- Option to choose an second image
- width and height fields for the second image
- postion vertical and horizontal field for the second image (like: top-left, top-center, top-right, center-left, center-center, center-right, bottom-left, bottom-center, bottom-right
- offset x/y field to to accurate positioning
It's not the very very important feature but on other hands its really good to do a bit unique stuff with images especially with share images
@khalwat First of all here is the code that I use. It's a bit mess but it works. The question is how can we combine that with SeoMatic?
My Thoughts:
Every IO Field should have this:
Fields below the lightswitch just visible when it's on
I need it just to create the OG Images Twitter / Facebook. Don't know if its a IO Feature or more a Seomatic Feature? What you think?
Don't know how the optimal way to bring it from IO to SeoMatic?
{# -- Custom Social Image -- #}
{% if (
(entry.entryImage ?? null) or
(seomaticSiteMeta.siteSeoImage is defined and seomaticSiteMeta.siteSeoImage | length )
) and (logo.globalLogo is defined and logo.globalLogo | length) %}
{# -- Set Logo -- #}
{% set logo = logo.globalLogo.first() %}
{# -- Imager: Watermark Image -- #}
{% set watermarkImage = craft.imager.transformImage(logo, [
{
width: 100,
height: 100
}], {
jpegQuality: 100,
})
%}
{# -- Watermark Image URL -- #}
{% set watermarkImage = watermarkImage[0].url %}
{# -- Check if Entry Image exists or use the default SEO Image -- #}
{% if entry.entryImage | length %}
{% set image = entry.entryImage.first() %}
{% else %}
{% set image = seomaticSiteMeta.siteSeoImage %}
{% endif %}
{# -- Check if Focal Point is set else use center center -- #}
{% if image.settingsFocalPoint is defined %}
{% set position = image.settingsFocalPoint %}
{% else %}
{% set position = '50% 50%' %}
{% endif %}
{# -- Imager: Entry / Default Image -- #}
{% set imageEntry = craft.imager.transformImage(image, [
{
width: 1200,
height: 630
}], {
jpegQuality: 100,
mode: 'crop',
position: position
})
%}
{# -- Entry / Default Image URL -- #}
{% set imageEntry = imageEntry[0].url %}
{# -- Imager: Share Image -- #}
{% set shareIamge = craft.imager.transformImage(imageEntry, [
{
width: 1200,
height: 630
}], {
jpegQuality: 100,
mode: 'crop',
ratio: '',
watermark: {
image: watermarkImage,
width: 100,
height: 100,
position: {
left: 30,
bottom: 30,
opacity: 0.8
}
}
})
%}
{# -- Share Image URL -- #}
{% set shareIamge = shareIamge[0].url %}
{# -- If Share Image exists -- #}
{% if shareIamge | length %}
{# -- Set Twitter Share Image -- #}
{% if seomaticMeta.twitter is defined and seomaticMeta.twitter is not empty %}
{% set twitter = seomaticMeta.twitter %}
{% set twitter = twitter | merge({'image': siteUrl|trim('/', 'right') ~ shareIamge}) %}
{% set seomaticMeta = seomaticMeta | merge({'twitter': twitter}) %}
{% endif %}
{# -- Set Default Share Image -- #}
{% set seomaticMeta = seomaticMeta | merge({'seoImage': siteUrl|trim('/', 'right') ~ shareIamge}) %}
{# -- Set Facebook Share Image -- #}
{% if seomaticMeta.og is defined and seomaticMeta.og is not empty %}
{% set og = seomaticMeta.og %}
{% set og = og | merge({
'image': siteUrl|trim('/', 'right') ~ shareIamge,
'image:width': '1200',
'image:height': '630',
'image:type': 'image/jpeg'
}) %}
{% set seomaticMeta = seomaticMeta | merge({'og': og}) %}
{% endif %}
{% endif %}
{% endif %}
Every Entry has an Entry Image:

This is my Image that I use to place the Watermark on it.
I think the option above is a good start point and a good solution to brand all images (maybe it needs a option to set a min size where watermarks be added) but the OG:Image, I think that's more a part to do that directly within the code or Seomatic and IO have a point of intersection.
Update the Fields

Thought about it again. I think to have watermarks on all images it's a fine solution. But for my Share Images that's more a Part within the Templates cause it's a bit to specific to append it to an image field. I don't need a Share Image from every Image.
Here is also the Updated Code. Think I create a Preparse Field to get it out of the Templates…
{# -- New Version -- #}
{# -- Share Image -- #}
{% if entry ?? null and entry.entryImage.one() ?? null and watermark.globalWatermark.one() ?? null %}
{% set watermarkField = watermark.globalWatermark.one() %}
{# -- Check if Watermark Using active -- #}
{% if watermarkField.useWatermark %}
{# -- Watermark Image -- #}
{% if watermarkField.image.one() ?? null %}
{% set watermarkImage = watermarkField.image.one() %}
{% set watermarkWidth = watermarkField.width %}
{% set watermarkHeight = watermarkField.height %}
{% set watermarkOpacity = watermarkField.opacity + 0 %}
{% set watermarkOffsetX = watermarkField.offsetXAxis %}
{% set watermarkOffsetY = watermarkField.offsetYAxis %}
{# -- Imager: Watermark Image -- #}
{% set watermarkImage = craft.imager.transformImage(watermarkImage, [
{ width: watermarkWidth, height: watermarkHeight }
], {
jpegQuality: 100
}) %}
{# -- Watermark Image URL -- #}
{% set watermarkImageUrl = watermarkImage[0].url %}
{% endif %}
{# -- Image Settings -- #}
{% set entryImage = entry.entryImage.one() %}
{% set focalpoint = entryImage.getFocalpoint('asCss') | default('50% 50%') %}
{# -- Facebook -- #}
{% set entryImageFacebook = craft.imager.transformImage(entryImage, [
{ width: 1200, height: 630 }
], {
jpegQuality: 100,
mode: 'crop',
position: focalpoint
}) %}
{% set entryImageFacebookUrl = entryImageFacebook[0].url %}
{# -- Imager: Share Image -- #}
{% set shareIamgeFacebook = craft.imager.transformImage(entryImageFacebookUrl, [
{
width: 1200,
height: 630
}], {
jpegQuality: 100,
mode: 'crop',
ratio: '',
watermark: {
image: watermarkImageUrl,
width: watermarkWidth,
height: watermarkHeight,
position: {
right: watermarkOffsetX,
bottom: watermarkOffsetY
},
opacity: watermarkOpacity
}
}) %}
{% set shareIamgeFacebookUrl = shareIamgeFacebook[0].url %}
{# -- Twitter -- #}
{% set entryImageTwitter = craft.imager.transformImage(entryImage, [
{ width: 1120, height: 600 }
], {
jpegQuality: 100,
mode: 'crop',
position: focalpoint
}) %}
{% set entryImageTwitterUrl = entryImageTwitter[0].url %}
{# -- Imager: Share Image -- #}
{% set shareIamgeTwitter = craft.imager.transformImage(entryImageTwitterUrl, [
{
width: 1120,
height: 600
}], {
jpegQuality: 100,
mode: 'crop',
ratio: '',
watermark: {
image: watermarkImageUrl,
width: watermarkWidth,
height: watermarkHeight,
position: {
right: watermarkOffsetX,
bottom: watermarkOffsetY
},
opacity: watermarkOpacity
}
}) %}
{% set shareIamgeTwitterUrl = shareIamgeTwitter[0].url %}
<meta property="og:image" content="{{ shareIamgeFacebookUrl }}" />
<meta property="og:image:type" content="image/jpeg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="{{ shareIamgeTwitterUrl }}" />
{% endif %}
{% endif %}