| 开发者 | opencluster |
|---|---|
| 更新时间 | 2026年8月24日 17:15 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.0 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
<img> source: SEO, social previews, and the no-JavaScript fallback.<canvas> with a blur-up cross-fade.
What it blocks (and what it honestly doesn't)
bender-mosaic-image-protection folder to /wp-content/plugins/, or install directly from the Plugins screen.Bender is a WordPress plugin that protects images from theft: it breaks them into an unreadable mosaic for scrapers and bots, shows visitors a live canvas reconstruction, and serves search engines a signed low-res version with a watermark and IPTC copyright metadata.
It blocks automated scrapers, hotlinking, and right-click "Save image", because the HTML never contains a plain hi-res URL. It cannot prevent a screenshot, because no web technology can — that's why every image is still signed with a watermark and IPTC metadata.
No — SEO stays intact and actually improves. The low-res version is a real <img> tag with alt text, indexable by Google Images, with IPTC metadata enabling the "Licensable" badge. CSS and JS together weigh about 4 KB with zero dependencies.
The sharp, watermarked low-res version. There's never a broken image; canvas reconstruction only happens if JavaScript is active.
Yes: align the token validity (24 hours by default) with your page cache duration.
No — only PHP 7.4+ with the GD extension, standard on virtually any WordPress hosting.
<img> tag carries no width/height attributes. The tag's only size reference then becomes the low-res file (480px wide) that replaces the original in src, so the image — and the frame around it — collapsed to that width. Bender now carries over the dimensions the tag had before protection, taken from the file it pointed to. The protected image also keeps a max-width of its own, for themes that size images with a child-combinator rule (.slide > img), which no longer matches once the image sits inside the frame.<img> was a block-level box with its own aspect ratio, so it — not the theme — decided the size: images sized by the theme through CSS rules on the img selector (logos capped to a fixed height, sliders with a minimum height) grew to their full aspect ratio, containers that took their height from the image collapsed or stretched, and margins coming from copied utility classes were applied twice. The frame is now a plain inline-block wrapper with no aspect ratio of its own, and the image inside keeps the width, height and object-fit the theme gave it, so the layout is identical to the same page without the plugin.<img> (or its <picture> wrapper) carried layout classes or inline styles — the common width:100%; height:100%; object-fit:cover inside a fixed-height container used by carousels, cards and hero sections — the frame that replaces it now inherits them, so the image keeps the width and height it had before.data-src/data-srcset (and the other usual lazy-load attributes) were left on the tag, so the lazy loader put the original image URL back into src as soon as the image entered the viewport.universal_scan) leaving <picture> elements (responsive images with multiple <source> breakpoints, e.g. carousels/sliders) completely unprotected: the hi-res URLs in the <source> tags bypassed the mosaic entirely, and the generated canvas ignored the width/height intended for that layout. <picture>/<source> are now replaced by the protected frame like a plain <img>, and the frame keeps the original width/height aspect ratio when set.universal_scan, added in 0.1.6): when the only protected image on a page was reached exclusively through this fallback, the mosaic viewer script/style were enqueued too late to ever be printed (the fallback rewrites the fully-buffered page, which closes after wp_head/wp_footer already ran), so visitors saw the static low-res <img> with no <canvas> upgrade — the image looked unprotected even though the server-side markup was correct. Assets are now enqueued as soon as the fallback decides to scan the page, before output buffering starts.<img> tags outside the_content()/the_post_thumbnail() (e.g. wp_get_attachment_image() called directly, or a raw <img src="..."> in a hand-built gallery/slider): those images were left completely unprotected before, even after marking the attachment as protected. Bender now also scans the fully rendered page and swaps in the protected version for any image it recognizes. New "Custom themes / page builders" setting to disable this if not needed.languages/, loaded automatically via load_plugin_textdomain() — no need to wait for community translations on translate.wordpress.org.bender-mosaic-image-protection text domain, instead of hardcoded Italian. Translators can now localize the plugin via translate.wordpress.org.$n/$opacity/$ttl-style parameters left over), so the free codebase itself contains no latent/dormant configurability for these values.bendmoim/BENDMOIM prefix (was bender/Bender, with one stray pg_rl_ transient key).