Selecting Text In Images - Pure SVG, No JavaScript


Recently, I wanted to embed an photograph of a book page. I thought it would be nifty if the text from the page could be selected.

If you hover your mouse over this image, you should be able to select part of the text.

Ideally, it will look something like this...

Selected Text

It even works on Android (tried on Chrome, Opera, FireFox) and iOS 7.

Android SVG Selection-fs8

So, how did I do it?

Originally, I was pointed to Project Naptha - it seems to do everything I want but is very JavaScript heavy and requires modern browser support.

I then turned to SVG - Scalable Vector Graphics.

The way I've done this is almost certainly wrong and I'd appreciate any advice about the proper way to render text in an SVG.

The first part is easy - displaying a PNG as the background to the SVG. In this case, I've taken the image and Base64 encoded it.

SVG SVG<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
  xmlns="http://www.w3.org/2000/svg"
  version="1.1"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="566"
  height="166"
>
<image xlink:href="data:image/png;base64,iVBORw0KGg...."
  x="0"
  y="0"
  width="566"
  height="166" />

The X & Y co-ordinates are from the top left. I've manually added in the height and width of the image.

Next, we add the text.

SVG SVG   <g fill-opacity="0">
      <text
        x="70"
        y="45"
        font-size="14"
        font-family="serif"
        textLength="415"
        lengthAdjust="spacingAndGlyphs">
         For nearly three years, between 1960 and 1963, MI5 and GCHQ
      </text>
      <text
        x="42"
        y="62"
        font-size="14"
        font-family="serif"
        textLength="440"
        lengthAdjust="spacingAndGlyphs">
         read the French high grade cipher coming in and out of the French
      </text>
      ...
   </g>
</svg>

As you can see, I've grouped the text together in a <g> element. I've set the opacity to zero - so while they are on top of the image, they cannot be seen unless selected. I've also manually split the lines and placed them on the image. I've set a "textLength" so that they'll fit across the page and automatically adjust themselves if they're too long.

This is very imprecise and quite time consuming. To get a better idea of how accurate (or not) it is, here's the same image, with the opacity set to 0.5.

Close enough, but not brilliant.

Finally, I've had to reference the images via an iframe. Without doing that, I wasn't able to select the text. I'm not sure if that's a browser fault, or expected functionality.

If you can suggest a quicker and more accurate way of doing this - I'd love for you to leave a comment below.


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

8 thoughts on “Selecting Text In Images - Pure SVG, No JavaScript”

  1. said on boing.world:

    @Edent In Brave on Android, I can press and hold to select a single word, but not across a word boundary... except the one time it did, and (a) I can't work out how I did that and (b) it made the selection handles visually disappear (but I could still ask my phone to read the selection). Whut.

    Reply | Reply to original comment on boing.world

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">