DEV Community

Discussion on: How to make Dynamic Text Overlays on Images

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Far from perfect. The isDark function is extremely naive. For example - if the image has a patch of light or dark that lines up with the text, and the rest of the image is of the opposite 'lightness', you are going to end up with unreadable text again.

What you need to do is test the part of the image that is actually underneath the text

Collapse
 
sarthology profile image
Sarthak Sharma

That's also doable, using the same concept and some more work in canvas.

Collapse
 
lysofdev profile image
Esteban Hernández

Would it be possible to identify the subset of pixels that represent the area under the text from the image data? Then we could reapply the algorithm to a smaller size making it significantly less complex. My main concern with the original implementation would be the cost of scanning a high-resolution image. The profiling algorithm could probably be best applied after the upload on the upload service itself and store the profiling data with the image then we can just fetch the image and it's profiling data and don't have to scan it on client's device.

Thread Thread
 
sarthology profile image
Sarthak Sharma

I think it can be. But it might take a lot of werid calculations to do something like that. But I’m up for the challenge. 😎

Thread Thread
 
kenbellows profile image
Ken Bellows • Edited

It's not too bad as long as you know (or can get) three things:

  • the size the image will be when rendered
  • the pixel position of the text relative to the top-left corner of the image
  • the approximate height and width of the text when rendered

That last bit is the hard part, especially if there's any line breaks involved. But after you have those, it's basically this:

const start = { x: img left + text rel left, y: img top + text rel top }
const end = { x: img left + text rel left + text width, y: img top + text rel top + text height }
for (const x = start.x; x < end.x; x++) {
  for (const y = start.y; y < end.y; y++) {
    const p = (canvas.width * y + x) * 4
    const [r, g, b] =[].slice.call(data, p, p+3)
    // fancy logic of choice
  }
}