6

I'm working on a page that will allow a webmaster to add styles to their twitter feed. Several of these styles use transparency in their display. I want to create a list of images for them to choose from. Currently I am taking screenshots on a checked background such as this:

enter image description here

But that isn't really what I want.

Is their some method of capturing an image of an HTML element, and maintaining the transparency?

EDIT: I'm just digging into this, so I'm coming across new topics, such as HTML5 Canvas, and -moz-element. Is it possible to set a canvas background to the html element using -moz-element, then extract the image data from the canvas? I'm going to try this unless someone who's 'been there done that' heads me off.

EDIT: The -moz-element and canvas was a deadend. -moz-element will set the item as a background, but will not allow you to save background image. And canvas doesn't save its background, even when the background is a normal image.

Community
  • 1
  • 1
BentFX
  • 2,746
  • 5
  • 25
  • 30
  • On a HTML document? Are you referring to a screenshot? – breezy May 18 '11 at 15:47
  • Yes it is HTML markup. I want an image that maintains the transparency of the HTML element. I guess screenshot really isn't the correct word, because a screenshot doesn't do what I want. – BentFX May 18 '11 at 15:53
  • 1
    Perhaps you should just display an actual preview (HTML and CSS in the page)? – Andrea May 18 '11 at 16:03
  • @Taze T. Schnitzel - I've thought of this, and consider it a possibility. It seems like it could turn into CSS hell. With a proper naming scheme it should be doable, but images would be still be simpler. – BentFX May 18 '11 at 16:23

4 Answers4

12

It requires a little bit of work, but it is doable, as long as it's HTML you're laying out. You can't recover the transparency of markup in pages you've downloaded without saving those pages and editing them locally. By rendering the HTML elements multiple times, on different background colors, the opacity can be derived using an image editor. You're going to need a decent image editor, I use GIMP.

  1. Render the elements you want to save three times, on a black, a white and a neutral gray background(#888).

  2. Using a screen capture program, capture those displays and crop them to the exact same areas.

  3. In GIMP open those images as layers and order them black, white and gray, top to bottom.

  4. Set the top, black layer to difference mode. This will give a grayscale difference between the black and white layers.

  5. Merge down the top layer. This will leave us with two layers. The gray background layer and the grayscale difference. Invert the colors of the difference layer, and copy it to the clipboard.

  6. Add a layer mask to the gray background layer and paste the clipboard into the layer mask.

  7. Delete the grayscale layer and apply the layer mask on the gray background layer. That should leave one layer with opacity similar to the original.

  8. The opacity is off by a bit, but if we duplicate the layer and merge it with itself, it's right in the ballpark.

It's probably not pixel perfect, but it is proof of concept. Opacity of HTML markup can be captured.

DerivedOpacity.jpg

BentFX
  • 2,746
  • 5
  • 25
  • 30
  • +1 Interesting solution. By using an embedded browser like the one in SWT, you might be able to automate most of the process. – Aaron Digulla Nov 05 '12 at 09:03
5

Using Puppeteer makes this much easier to do. It runs a web-page in-memory.

Start a local fileserver - python -m SimpleHTTPServer 8080

Then this script should do the trick:

const puppeteer = require('puppeteer')

;(async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page.goto('http://localhost:8080/index.html', {
    waitUntil: 'networkidle0'
  })
  const elements = await page.$('body')
  await page.evaluate(() => (document.body.style.background = 'transparent'))
  await elements.screenshot({ path: 'myImg.png', omitBackground: true })
  await browser.close()
})()

the docs for .screenshot() are here.

spencercooly
  • 6,548
  • 2
  • 23
  • 15
1

What you'd need is a web browser that can render into an image buffer in memory instead of the screen.

My guess is that all browsers can do this (that should be part of the renderers) but I'm not aware of any browser where you can access this function, at least not from JavaScript.

If you download the WebKit sources, there should be test cases which do something like that :-/

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • This is along the lines of what I want, and fits with my expectation of how it would be accomplished. Yet I had hoped for an existing solution. I am not in a position to learn a new programming language, just to solve this issue. :) (Yet I will look at WebKit for examples that might be usable with little editing) Thanks! – BentFX May 18 '11 at 16:17
  • Well, the automated tests of WebKit should run during the build. So this approach should get you almost where you want to be. – Aaron Digulla May 19 '11 at 12:35
  • I never got too far on the WebKit trail. I went to the #WebKit irc on freenode.net and was told this isn't possible with the existing code. – BentFX May 20 '11 at 12:20
  • Hey Aaron, sorry I took your check away. About six months ago I figured out my answer, but just got around to writing it up. Your's would be the perfect solution if those responsible for the code saw fit to make it an option. My solution works and once you've got the work-flow in mind it is possible to recover opacity from a whole screen full of elements quickly. Thanks again! – BentFX Nov 04 '12 at 22:46
-1

No, there's no software that will allow you to take screenshots and preserve the transparency of individual visual elements as a transparent spot in the image, because that's not how a screenshot works - screenshots are WYSIWYG, by definition, all elements in your screenshot will always have a non-transparent background.

I think your best bet here is to recreate the desired portion as an image, where you can control the transparency normally. It's not the best solution, but if you're doing this a lot with the same kinds of things, it will be much faster for you rather than cropping/editing screenshots.

rlb.usa
  • 14,942
  • 16
  • 80
  • 128