Transparent screenshot with headless ChromeDriver via Selenium
One way would be to convert each white pixel to a transparent pixel from the screenshot by setting the alpha byte to 0:
from selenium import webdriver
from PIL import Image
from io import BytesIO # python 3
import numpy as np
def remove_color(img, rgba):
data = np.array(img.convert('RGBA')) # rgba array from image
pixels = data.view(dtype=np.uint32)[...,0] # pixels as rgba uint32
data[...,3] = np.where(pixels == np.uint32(rgba), np.uint8(0), np.uint8(255)) # set alpha channel
return Image.fromarray(data)
driver = webdriver.Chrome()
driver.get("http://www.bbc.co.uk/news")
# take screenshot with a transparent background
with Image.open(BytesIO(driver.get_screenshot_as_png())) as img :
with remove_color(img, 0xffffffff) as img2:
img2.save(r"C:\temp\screenshot.png")
However you may end up with some unexpected transparent pixels if the page content has some white pixels and the antialiassing will probably be visible.
Another solution is to use the DevTool API with Chrome to exclude the background from the screenshot:
from selenium import webdriver
import json
def send(cmd, params={}):
resource = "/session/%s/chromium/send_command_and_get_result" % driver.session_id
url = driver.command_executor._url + resource
body = json.dumps({'cmd':cmd, 'params': params})
response = driver.command_executor._request('POST', url, body)
if response['status']: raise Exception(response.get('value'))
return response.get('value')
options = webdriver.ChromeOptions()
options.add_argument("disable-gpu")
options.add_argument("disable-infobars")
driver = webdriver.Chrome(chrome_options=options)
driver.get("http://www.bbc.co.uk/news")
# take screenshot with a transparent background
send("Emulation.setDefaultBackgroundColorOverride", {'color': {'r': 0, 'g': 0, 'b': 0, 'a': 0}})
driver.get_screenshot_as_file(r"C:\temp\screenshot.png")
send("Emulation.setDefaultBackgroundColorOverride") # restore
A png can have transparent pixels, but a screenshot cannot. Whenever you render something you mix the rendering looking at transparency levels of layers, but the combine layer will always have a background.
A screenshot is of what has been rendered on screen and it can never be transparent. How do you display a true transparent image on a desktop? You can't because the background of desktop or something else will always have to be there.
So what you are asking has nothing to do with Chrome, ChromeDriver. Any screenshot taking tool cannot take a transparent screenshot, without you telling it what to mask.
Even tools like Photoshop use special way (grey color boxes with small changes) to show transparent background, but if you use a screenshot tool to capture that image the result would be a image with actual pixel and no transparency like below