You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by "srijani-smsrc (via GitHub)" <gi...@apache.org> on 2026/04/13 07:42:38 UTC

[D] BRANDING ON DOWNLOADED IMAGES [superset]

GitHub user srijani-smsrc created a discussion: BRANDING ON DOWNLOADED IMAGES

6. BRANDING ON DOWNLOADED IMAGES — "Powered by xyz" (my feedback)
Superset's export generates plain screenshots. However, we can customise this at two levels: (a) add a Markdown component with the xyz branding at the footer of each dashboard so it appears in screenshots, or (b) write a lightweight post-processing script that overlays branding on exported images. This is solvable.


how to do this for all image download and csv download

@dosubot

GitHub link: https://github.com/apache/superset/discussions/39323

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "srijani-smsrc (via GitHub)" <gi...@apache.org>.
GitHub user srijani-smsrc added a comment to the discussion: BRANDING ON DOWNLOADED IMAGES

i did option 1 but there is no effect in download as image for tables or charts

@dosubot


GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16543050

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "dosubot[bot] (via GitHub)" <gi...@apache.org>.
GitHub user dosubot[bot] edited a comment on the discussion: BRANDING ON DOWNLOADED IMAGES

<!-- Answer -->
You've reached the anonymous usage limit of `10` interactions per month. Your usage will reset on `2026-05-01`. If you'd like to use Dosu before then, please [register](https://app.dosu.dev/login?referrer=from-anonymous-rate-limit) to increase your limit to `100` interactions per month for free.


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=reply-with-mention&utm_term=apache%2Fsuperset).*

---

Share context across your team and agents. Try [Dosu](https://dosu.dev?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-tagline&utm_term=apache%2Fsuperset).

[![Leave Feedback](https://img.shields.io/badge/Leave%20Feedback-555555?style=flat)](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-feedback&utm_term=apache%2Fsuperset&message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda) [![Learn about superset with Dosu](https://img.shields.io/badge/Learn%20about%20superset%20with%20Dosu-2f7b3f?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iODYiIGhlaWdodD0iODkiIHZpZXdCb3g9IjAgMCA4NiA4OSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4yOTIzNiAxMi43OTI4TDE3Ljc1OTMgNi42ODE4OFY3Mi41NjY3TDUuMjkyMzYgODQuMDYxOFYxMi43OTI4WiIgZmlsbD0iI0I0QkI5MSIvPjxwYXRoIGQ9Ik0xOC4yNTc1IDczLjExOTZMNTkuMTMyOSA3Mi43NDhMNTEuNzAxMSA4Mi40MDk1TDI5LjAzMzggODYuMjkxTDYuMjM5NjIgODUuMTU1NEwxOC4yNTc1IDczLjExOTZaIiBmaWxsPSIjNzc4NTYxIi8%2BPHBhdGggZD0iTTE3LjQ5MTYgMy43MzYzM0wzLjU4NTU3IDEyLjcwOTlWODMuNTc5MkMzLjU4NTU3IDg0Ljc1NDIgNC4
 5ODU2MyA4NS4zNjUyIDUuODQ3MDUgODQuNTY2TDE5LjYyOTYgNzEuNzgwMSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSI2LjQyODQ0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48bWFzayBpZD0iZG9zdS1kLWN1dG91dCIgZmlsbD0id2hpdGUiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNDAuNzA0IDAuNTE4MDY2SDE3LjA0MzlWNzYuMjIyMUg0MC43MDRINDIuNTgwNUg0Ny44MDEzQzY4LjcwNjQgNzYuMjIyMSA4NS42NTMzIDU5LjI3NTIgODUuNjUzMyAzOC4zNzAxQzg1LjY1MzMgMTcuNDY1IDY4LjcwNjMgMC41MTgwNjYgNDcuODAxMyAwLjUxODA2Nkg0Mi41ODA1SDQwLjcwNFoiLz48L21hc2s%2BPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MC43MDQgMC41MTgwNjZIMTcuMDQzOVY3Ni4yMjIxSDQwLjcwNEg0Mi41ODA1SDQ3LjgwMTNDNjguNzA2NCA3Ni4yMjIxIDg1LjY1MzMgNTkuMjc1MiA4NS42NTMzIDM4LjM3MDFDODUuNjUzMyAxNy40NjUgNjguNzA2MyAwLjUxODA2NiA0Ny44MDEzIDAuNTE4MDY2SDQyLjU4MDVINDAuNzA0WiIgZmlsbD0iI0YzRjZGMSIvPjxwYXRoIGQ9Ik0xNy4wNDM5IDAuNTE4MDY2Vi02LjU3OTE5SDkuOTQ2NjlWMC41MTgwNjZIMTcuMDQzOVpNMTcuMDQzOSA3Ni4yMjIxSDkuOTQ2NjlWODMuMzE5NEgxNy4wNDM5Vjc2LjIyMjFaTTE3LjA0MzkgNy42MTUzMkg0MC43MDRWLTYuNT
 c5MTlIMTcuMDQzOVY3LjYxNTMyWk0yNC4xNDEyIDc2LjIyMjFWMC41MTgwNjZIOS45NDY2OVY3Ni4yMjIxSDI0LjE0MTJaTTQwLjcwNCA2OS4xMjQ5SDE3LjA0MzlWODMuMzE5NEg0MC43MDRWNjkuMTI0OVpNNDIuNTgwNSA2OS4xMjQ5SDQwLjcwNFY4My4zMTk0SDQyLjU4MDVWNjkuMTI0OVpNNDcuODAxMyA2OS4xMjQ5SDQyLjU4MDVWODMuMzE5NEg0Ny44MDEzVjY5LjEyNDlaTTc4LjU1NiAzOC4zNzAxQzc4LjU1NiA1NS4zNTU1IDY0Ljc4NjcgNjkuMTI0OSA0Ny44MDEzIDY5LjEyNDlWODMuMzE5NEM3Mi42MjYxIDgzLjMxOTQgOTIuNzUwNSA2My4xOTQ5IDkyLjc1MDUgMzguMzcwMUg3OC41NTZaTTQ3LjgwMTMgNy42MTUzMkM2NC43ODY2IDcuNjE1MzIgNzguNTU2IDIxLjM4NDcgNzguNTU2IDM4LjM3MDFIOTIuNzUwNUM5Mi43NTA1IDEzLjU0NTMgNzIuNjI2IC02LjU3OTE5IDQ3LjgwMTMgLTYuNTc5MTlWNy42MTUzMlpNNDIuNTgwNSA3LjYxNTMySDQ3LjgwMTNWLTYuNTc5MTlINDIuNTgwNVY3LjYxNTMyWk00MC43MDQgNy42MTUzMkg0Mi41ODA1Vi02LjU3OTE5SDQwLjcwNFY3LjYxNTMyWiIgZmlsbD0iYmxhY2siIG1hc2s9InVybCgjZG9zdS1kLWN1dG91dCkiLz48cGF0aCBkPSJNNjguOTIxNSAzNi4wMTM1QzY4LjkyMTUgMzYuMDEzNSA2NS43MzY5IDQ5LjQ3MzggNTEuNDIzMSA0OS40NzM4QzM3LjEwOTMgNDkuNDczOCAzMi41Nzg3IDM3LjM1OTYgMzIuNTc4NyAzNi4wMTM1IiBzdHJva2U9ImJsYWNrIiB
 zdHJva2Utd2lkdGg9IjcuNjkxNjEiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0wLjM0ODYzMyA4NS40OTQ2QzAuMzQ4NjMzIDg1LjQ5NDYgMjkuNDg1NiA4NS44MzA5IDM0LjgwOSA4NS42OThDNDQuODMzNyA4NS40NDc3IDUxLjI4NzIgODQuNDAyIDU3LjUyNjkgNzguOTcyNEM2Mi44MTI5IDc0LjM3MjcgNzUuMTM0MiA1OS42ODM2IDc1LjEzNDIgNTkuNjgzNiIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSI2LjE2NDgyIi8%2BPC9zdmc%2B)](https://github.dosu.com/apache/superset?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-learn-repo&utm_term=apache%2Fsuperset) [![Add Dosu to your team](https://img.shields.io/badge/Add%20Dosu%20to%20your%20team-1f6feb?style=flat)](https://app.dosu.dev/signup?referrer=openSource&source=github-footer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-add-team&utm_term=apache%2Fsuperset)

GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16543052

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "dosubot[bot] (via GitHub)" <gi...@apache.org>.
GitHub user dosubot[bot] added a comment to the discussion: BRANDING ON DOWNLOADED IMAGES

<!-- Answer -->
Superset does **not** have a built-in "Powered by xyz" branding feature for exports, so you'll need code modifications. Here's how to approach it for each export type:

**For image/screenshot exports**, the best approach is to post-process images in the screenshot pipeline. Superset already uses PIL/Pillow for image resizing in `superset/utils/screenshots.py` [[1]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py), so you can add a watermark step after capture:

```python
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO

def add_watermark(image_bytes):
    img = Image.open(BytesIO(image_bytes))
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("Arial.ttf", 20)
    draw.text((10, img.height - 30), "Powered by xyz", fill="gray", font=font)
    output = BytesIO()
    img.save(output, format="PNG")
    return output.getvalue()
```

Hook this into the `get_screenshot()` or `compute()` method of the `BaseScreenshot` class [[2]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L149-L277). An alternative is to add a visible watermark DOM element in the frontend React components — since screenshots capture the rendered browser UI, it would automatically appear in exports too.

**For CSV exports**, modify the `df_to_escaped_csv()` function in `superset/utils/csv.py` [[3]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/csv.py#L67-L81) to append a branding footer row to the DataFrame before conversion:

```python
# Before converting to CSV
import pandas as pd
footer = pd.DataFrame([{df.columns[0]: "Powered by xyz"}])
df = pd.concat([df, footer], ignore_index=True)
```

This affects both SQL Lab exports (`superset/commands/sql_lab/export.py`) and chart data exports [[4]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/commands/sql_lab/export.py).

**For a less invasive approach**, you can use `FLASK_APP_MUTATOR` in `superset_config.py` to intercept export responses globally via a Flask `after_request` hook — though modifying binary image content in a response handler is more complex than doing it in the screenshot pipeline directly.

Note that all of these require modifying Superset's source code; there's no config-only solution for export branding. The CSV footer approach is the simplest, while the screenshot watermarking gives the most professional result for images.

Would you like me to look deeper into any specific export path (e.g., email/PDF reports, or the exact code locations to modify)?


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).*

---
<sup>How did I do? [Good](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response#message_id=f40d3082-6730-40d5-bea1-bd13bdc66521&feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer#message_id=f40d3082-6730-40d5-bea1-bd13bdc66521&feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources#message_id=f40d3082-6730-40d5-bea1-bd13bdc66521&feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose#message_id=f40d3082-6730-40d5-bea1-bd13bdc66521&feedback_type=too_verbose) | [Hallucination](https://app
 .dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination#message_id=f40d3082-6730-40d5-bea1-bd13bdc66521&feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report#message_id=f40d3082-6730-40d5-bea1-bd13bdc66521&feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other#message_id=f40d3082-6730-40d5-bea1-bd13bdc66521&feedback_type=other)</sup>
[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=Superset%20does%20%2A%2Anot%2A%2A%20have%20a%20built-in%20%22Powered%20by%20xyz%22%20branding%20feature%20for%20exports%2C%20so%20you%27ll%20need%20code%20modifications.%20Here%27s%20how%20to%20approach%20it%20for%20each%20export%20type%3A%0A%0A%2A%2AFor%20image/screenshot%20exports%2A%2A%2C%20the%20best%20approach%20is%20to%20post-process%20images%20in%20the%20screenshot%20pipeline.%20Superset%20already%20uses%20PIL/Pillow%20for%20image%20resizing%20in%20%60superset/utils/screenshots.py%60%20%5B%5B1%5D%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py%29%2C%20so%20you%20can%20add%20a%20watermark%20step%20afte
 r%20capture%3A%0A%0A%60%60%60python%0Afrom%20PIL%20import%20Image%2C%20ImageDraw%2C%20ImageFont%0Afrom%20io%20import%20BytesIO%0A%0Adef%20add_watermark%28image_bytes%29%3A%0A%20%20%20%20img%20%3D%20Image.open%28BytesIO%28image_bytes%29%29%0A%20%20%20%20draw%20%3D%20ImageDraw.Draw%28img%29%0A%20%20%20%20font%20%3D%20ImageFont.truetype%28%22Arial.ttf%22%2C%2020%29%0A%20%20%20%20draw.text%28%2810%2C%20img.height%20-%2030%29%2C%20%22Powered%20by%20xyz%22%2C%20fill%3D%22gray%22%2C%20font%3Dfont%29%0A%20%20%20%20output%20%3D%20BytesIO%28%29%0A%20%20%20%20img.save%28output%2C%20format%3D%22PNG%22%29%0A%20%20%20%20return%20output.getvalue%28%29%0A%60%60%60%0A%0AHook%20this%20into%20the%20%60get_screenshot%28%29%60%20or%20%60compute%28%29%60%20method%20of%20the%20%60BaseScreenshot%60%20class%20%5B%5B2%5D%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py%23L149-L277%29.%20An%20alternative%20is%20to%20add%20a%20visible%20water
 mark%20DOM%20element%20in%20the%20frontend%20React%20components%20%E2%80%94%20since%20screenshots%20capture%20the%20rendered%20browser%20UI%2C%20it%20would%20automatically%20appear%20in%20exports%20too.%0A%0A%2A%2AFor%20CSV%20exports%2A%2A%2C%20modify%20the%20%60df_to_escaped_csv%28%29%60%20function%20in%20%60superset/utils/csv.py%60%20%5B%5B3%5D%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/csv.py%23L67-L81%29%20to%20append%20a%20branding%20footer%20row%20to%20the%20DataFrame%20before%20conversion%3A%0A%0A%60%60%60python%0A%23%20Before%20converting%20to%20CSV%0Aimport%20pandas%20as%20pd%0Afooter%20%3D%20pd.DataFrame%28%5B%7Bdf.columns%5B0%5D%3A%20%22Powered%20by%20xyz%22%7D%5D%29%0Adf%20%3D%20pd.concat%28%5Bdf%2C%20footer%5D%2C%20ignore_index%3DTrue%29%0A%60%60%60%0A%0AThis%20affects%20both%20SQL%20Lab%20exports%20%28%60superset/commands/sql_lab/export.py%60%29%20and%20chart%20data%20exports%20%5B%5B4%5D%5D%28https%3A//github
 .com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/commands/sql_lab/export.py%29.%0A%0A%2A%2AFor%20a%20less%20invasive%20approach%2A%2A%2C%20you%20can%20use%20%60FLASK_APP_MUTATOR%60%20in%20%60superset_config.py%60%20to%20intercept%20export%20responses%20globally%20via%20a%20Flask%20%60after_request%60%20hook%20%E2%80%94%20though%20modifying%20binary%20image%20content%20in%20a%20response%20handler%20is%20more%20complex%20than%20doing%20it%20in%20the%20screenshot%20pipeline%20directly.%0A%0ANote%20that%20all%20of%20these%20require%20modifying%20Superset%27s%20source%20code%3B%20there%27s%20no%20config-only%20solution%20for%20export%20branding.%20The%20CSV%20footer%20approach%20is%20the%20simplest%2C%20while%20the%20screenshot%20watermarking%20gives%20the%20most%20professional%20result%20for%20images.%0A%0AWould%20you%20like%20me%20to%20look%20deeper%20into%20any%20specific%20export%20path%20%28e.g.%2C%20email/PDF%20reports%2C%20or%20the%20exact%20code%20locat
 ions%20to%20modify%29%3F)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/discussions/39323)

GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16540789

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "dosubot[bot] (via GitHub)" <gi...@apache.org>.
GitHub user dosubot[bot] edited a comment on the discussion: BRANDING ON DOWNLOADED IMAGES

<!-- Answer -->
Superset does **not** have a built-in "Powered by xyz" branding feature for exports, so you'll need code modifications. Here's how to approach it for each export type:

**For image/screenshot exports**, the best approach is to post-process images in the screenshot pipeline. Superset already uses PIL/Pillow for image resizing in `superset/utils/screenshots.py` [[1]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py), so you can add a watermark step after capture:

```python
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO

def add_watermark(image_bytes):
    img = Image.open(BytesIO(image_bytes))
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("Arial.ttf", 20)
    draw.text((10, img.height - 30), "Powered by xyz", fill="gray", font=font)
    output = BytesIO()
    img.save(output, format="PNG")
    return output.getvalue()
```

Hook this into the `get_screenshot()` or `compute()` method of the `BaseScreenshot` class [[2]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L149-L277). An alternative is to add a visible watermark DOM element in the frontend React components — since screenshots capture the rendered browser UI, it would automatically appear in exports too.

**For CSV exports**, modify the `df_to_escaped_csv()` function in `superset/utils/csv.py` [[3]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/csv.py#L67-L81) to append a branding footer row to the DataFrame before conversion:

```python
# Before converting to CSV
import pandas as pd
footer = pd.DataFrame([{df.columns[0]: "Powered by xyz"}])
df = pd.concat([df, footer], ignore_index=True)
```

This affects both SQL Lab exports (`superset/commands/sql_lab/export.py`) and chart data exports [[4]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/commands/sql_lab/export.py).

**For a less invasive approach**, you can use `FLASK_APP_MUTATOR` in `superset_config.py` to intercept export responses globally via a Flask `after_request` hook — though modifying binary image content in a response handler is more complex than doing it in the screenshot pipeline directly.

Note that all of these require modifying Superset's source code; there's no config-only solution for export branding. The CSV footer approach is the simplest, while the screenshot watermarking gives the most professional result for images.

Would you like me to look deeper into any specific export path (e.g., email/PDF reports, or the exact code locations to modify)?


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=reply-with-mention&utm_term=apache%2Fsuperset).*

---

Docs are dead. Just use [Dosu](https://dosu.dev?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=static-docs-tagline&utm_term=apache%2Fsuperset).

[![Leave Feedback](https://img.shields.io/badge/Leave%20Feedback-555555?style=flat)](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=static-docs-feedback&utm_term=apache%2Fsuperset&message_id=f40d3082-6730-40d5-bea1-bd13bdc66521) [![Ask Dosu about superset](https://img.shields.io/badge/Ask%20Dosu%20about%20superset-2f7b3f?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iODYiIGhlaWdodD0iODkiIHZpZXdCb3g9IjAgMCA4NiA4OSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4yOTIzNiAxMi43OTI4TDE3Ljc1OTMgNi42ODE4OFY3Mi41NjY3TDUuMjkyMzYgODQuMDYxOFYxMi43OTI4WiIgZmlsbD0iI0I0QkI5MSIvPjxwYXRoIGQ9Ik0xOC4yNTc1IDczLjExOTZMNTkuMTMyOSA3Mi43NDhMNTEuNzAxMSA4Mi40MDk1TDI5LjAzMzggODYuMjkxTDYuMjM5NjIgODUuMTU1NEwxOC4yNTc1IDczLjExOTZaIiBmaWxsPSIjNzc4NTYxIi8%2BPHBhdGggZD0iTTE3LjQ5MTYgMy43MzYzM0wzLjU4NTU3IDEyLjcwOTlWODMuNTc5MkMzLjU4NTU3IDg0Ljc1NDIgNC45ODU2MyA4NS4zNjUyIDUuODQ3MDUg
 ODQuNTY2TDE5LjYyOTYgNzEuNzgwMSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSI2LjQyODQ0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48bWFzayBpZD0iZG9zdS1kLWN1dG91dCIgZmlsbD0id2hpdGUiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNDAuNzA0IDAuNTE4MDY2SDE3LjA0MzlWNzYuMjIyMUg0MC43MDRINDIuNTgwNUg0Ny44MDEzQzY4LjcwNjQgNzYuMjIyMSA4NS42NTMzIDU5LjI3NTIgODUuNjUzMyAzOC4zNzAxQzg1LjY1MzMgMTcuNDY1IDY4LjcwNjMgMC41MTgwNjYgNDcuODAxMyAwLjUxODA2Nkg0Mi41ODA1SDQwLjcwNFoiLz48L21hc2s%2BPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MC43MDQgMC41MTgwNjZIMTcuMDQzOVY3Ni4yMjIxSDQwLjcwNEg0Mi41ODA1SDQ3LjgwMTNDNjguNzA2NCA3Ni4yMjIxIDg1LjY1MzMgNTkuMjc1MiA4NS42NTMzIDM4LjM3MDFDODUuNjUzMyAxNy40NjUgNjguNzA2MyAwLjUxODA2NiA0Ny44MDEzIDAuNTE4MDY2SDQyLjU4MDVINDAuNzA0WiIgZmlsbD0iI0YzRjZGMSIvPjxwYXRoIGQ9Ik0xNy4wNDM5IDAuNTE4MDY2Vi02LjU3OTE5SDkuOTQ2NjlWMC41MTgwNjZIMTcuMDQzOVpNMTcuMDQzOSA3Ni4yMjIxSDkuOTQ2NjlWODMuMzE5NEgxNy4wNDM5Vjc2LjIyMjFaTTE3LjA0MzkgNy42MTUzMkg0MC43MDRWLTYuNTc5MTlIMTcuMDQzOVY3LjYxNTMyWk0
 yNC4xNDEyIDc2LjIyMjFWMC41MTgwNjZIOS45NDY2OVY3Ni4yMjIxSDI0LjE0MTJaTTQwLjcwNCA2OS4xMjQ5SDE3LjA0MzlWODMuMzE5NEg0MC43MDRWNjkuMTI0OVpNNDIuNTgwNSA2OS4xMjQ5SDQwLjcwNFY4My4zMTk0SDQyLjU4MDVWNjkuMTI0OVpNNDcuODAxMyA2OS4xMjQ5SDQyLjU4MDVWODMuMzE5NEg0Ny44MDEzVjY5LjEyNDlaTTc4LjU1NiAzOC4zNzAxQzc4LjU1NiA1NS4zNTU1IDY0Ljc4NjcgNjkuMTI0OSA0Ny44MDEzIDY5LjEyNDlWODMuMzE5NEM3Mi42MjYxIDgzLjMxOTQgOTIuNzUwNSA2My4xOTQ5IDkyLjc1MDUgMzguMzcwMUg3OC41NTZaTTQ3LjgwMTMgNy42MTUzMkM2NC43ODY2IDcuNjE1MzIgNzguNTU2IDIxLjM4NDcgNzguNTU2IDM4LjM3MDFIOTIuNzUwNUM5Mi43NTA1IDEzLjU0NTMgNzIuNjI2IC02LjU3OTE5IDQ3LjgwMTMgLTYuNTc5MTlWNy42MTUzMlpNNDIuNTgwNSA3LjYxNTMySDQ3LjgwMTNWLTYuNTc5MTlINDIuNTgwNVY3LjYxNTMyWk00MC43MDQgNy42MTUzMkg0Mi41ODA1Vi02LjU3OTE5SDQwLjcwNFY3LjYxNTMyWiIgZmlsbD0iYmxhY2siIG1hc2s9InVybCgjZG9zdS1kLWN1dG91dCkiLz48cGF0aCBkPSJNNjguOTIxNSAzNi4wMTM1QzY4LjkyMTUgMzYuMDEzNSA2NS43MzY5IDQ5LjQ3MzggNTEuNDIzMSA0OS40NzM4QzM3LjEwOTMgNDkuNDczOCAzMi41Nzg3IDM3LjM1OTYgMzIuNTc4NyAzNi4wMTM1IiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjcuNjkxNjEi
 IHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0wLjM0ODYzMyA4NS40OTQ2QzAuMzQ4NjMzIDg1LjQ5NDYgMjkuNDg1NiA4NS44MzA5IDM0LjgwOSA4NS42OThDNDQuODMzNyA4NS40NDc3IDUxLjI4NzIgODQuNDAyIDU3LjUyNjkgNzguOTcyNEM2Mi44MTI5IDc0LjM3MjcgNzUuMTM0MiA1OS42ODM2IDc1LjEzNDIgNTkuNjgzNiIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSI2LjE2NDgyIi8%2BPC9zdmc%2B)](https://github.dosu.com/apache/superset?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=static-docs-ask-repo&utm_term=apache%2Fsuperset) [![Share Dosu with your team](https://img.shields.io/badge/Share%20Dosu%20with%20your%20team-1f6feb?style=flat)](https://app.dosu.dev/signup?referrer=openSource&source=github-footer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=static-docs-share-team&utm_term=apache%2Fsuperset)

GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16540789

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "dosubot[bot] (via GitHub)" <gi...@apache.org>.
GitHub user dosubot[bot] added a comment to the discussion: BRANDING ON DOWNLOADED IMAGES

<!-- Answer -->
In `superset/utils/screenshots.py`, there are **two places** you should consider, depending on what you want to watermark:

**Option 1 (Recommended) — In `compute_and_cache()`, after the screenshot is captured but before caching (around line 270)**

This is the best spot because it watermarks the **full-resolution** image before any resizing for thumbnails. Insert your watermark call right after the `resize_image` block and before the cache update [[1]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L259-L275):

```python
        # line 259
        image = self.get_screenshot(user=user, window_size=window_size)
    except Exception as ex:
        logger.warning("Failed at generating thumbnail %s", ex, exc_info=True)
        cache_payload.error()
    if image and window_size != thumb_size:
        try:
            image = self.resize_image(image, thumb_size=thumb_size)
        except Exception as ex:
            logger.warning("Failed at resizing thumbnail %s", ex, exc_info=True)
            cache_payload.error()
            image = None

    # ✅ ADD WATERMARK HERE (after line 269, before line 271)
    if image:
        image = self.add_watermark(image)

    if image:
        logger.info("Caching thumbnail: %s", cache_key)
```

Then add this as a static/class method on `BaseScreenshot` [[2]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L279-L302):

```python
@staticmethod
def add_watermark(img_bytes: bytes) -> bytes:
    from PIL import ImageDraw, ImageFont
    img = Image.open(BytesIO(img_bytes))
    draw = ImageDraw.Draw(img)
    try:
        font = ImageFont.truetype("Arial.ttf", 20)
    except OSError:
        font = ImageFont.load_default()
    draw.text((10, img.height - 30), "Powered by xyz", fill="gray", font=font)
    output = BytesIO()
    img.save(output, format="PNG")
    return output.getvalue()
```

**Option 2 — Inside `resize_image()`, after the resize on line 296**

If you only want to watermark thumbnails (not full-size screenshots), insert it inside `resize_image()` between line 296 and 297 [[3]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L296-L302):

```python
    img = img.resize(thumb_size, Image.Resampling.LANCZOS)
    
    # ✅ ADD WATERMARK HERE
    draw = ImageDraw.Draw(img)
    try:
        font = ImageFont.truetype("Arial.ttf", 20)
    except OSError:
        font = ImageFont.load_default()
    draw.text((10, img.height - 30), "Powered by xyz", fill="gray", font=font)
    
    new_img = BytesIO()
```

**Important caveat:** Note that `resize_image()` is only called when `window_size != thumb_size` [[4]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L263-L265). If they're equal, `resize_image()` is skipped entirely, so the watermark wouldn't be applied. That's why **Option 1 is recommended** — it catches all screenshots regardless.

Both `ChartScreenshot` and `DashboardScreenshot` inherit from `BaseScreenshot` [[5]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L305-L363), so your watermark will apply to both chart and dashboard exports automatically.


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).*

---
<sup>How did I do? [Good](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response#message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492&feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer#message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492&feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources#message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492&feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose#message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492&feedback_type=too_verbose) | [Hallucination](https://app
 .dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination#message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492&feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report#message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492&feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other#message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492&feedback_type=other)</sup>
[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=In%20%60superset/utils/screenshots.py%60%2C%20there%20are%20%2A%2Atwo%20places%2A%2A%20you%20should%20consider%2C%20depending%20on%20what%20you%20want%20to%20watermark%3A%0A%0A%2A%2AOption%201%20%28Recommended%29%20%E2%80%94%20In%20%60compute_and_cache%28%29%60%2C%20after%20the%20screenshot%20is%20captured%20but%20before%20caching%20%28around%20line%20270%29%2A%2A%0A%0AThis%20is%20the%20best%20spot%20because%20it%20watermarks%20the%20%2A%2Afull-resolution%2A%2A%20image%20before%20any%20resizing%20for%20thumbnails.%20Insert%20your%20watermark%20call%20right%20after%20the%20%60resize_image%60%20block%20and%20before%20the%20cache%20update%20%5B%5B1%5D%5D%28https%3A//github.com/ap
 ache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py%23L259-L275%29%3A%0A%0A%60%60%60python%0A%20%20%20%20%20%20%20%20%23%20line%20259%0A%20%20%20%20%20%20%20%20image%20%3D%20self.get_screenshot%28user%3Duser%2C%20window_size%3Dwindow_size%29%0A%20%20%20%20except%20Exception%20as%20ex%3A%0A%20%20%20%20%20%20%20%20logger.warning%28%22Failed%20at%20generating%20thumbnail%20%25s%22%2C%20ex%2C%20exc_info%3DTrue%29%0A%20%20%20%20%20%20%20%20cache_payload.error%28%29%0A%20%20%20%20if%20image%20and%20window_size%20%21%3D%20thumb_size%3A%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20image%20%3D%20self.resize_image%28image%2C%20thumb_size%3Dthumb_size%29%0A%20%20%20%20%20%20%20%20except%20Exception%20as%20ex%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20logger.warning%28%22Failed%20at%20resizing%20thumbnail%20%25s%22%2C%20ex%2C%20exc_info%3DTrue%29%0A%20%20%20%20%20%20%20%20%20%20%20%20cache_payload.error%28%29%0A%20%20%20%20%20%20%20%
 20%20%20%20%20image%20%3D%20None%0A%0A%20%20%20%20%23%20%E2%9C%85%20ADD%20WATERMARK%20HERE%20%28after%20line%20269%2C%20before%20line%20271%29%0A%20%20%20%20if%20image%3A%0A%20%20%20%20%20%20%20%20image%20%3D%20self.add_watermark%28image%29%0A%0A%20%20%20%20if%20image%3A%0A%20%20%20%20%20%20%20%20logger.info%28%22Caching%20thumbnail%3A%20%25s%22%2C%20cache_key%29%0A%60%60%60%0A%0AThen%20add%20this%20as%20a%20static/class%20method%20on%20%60BaseScreenshot%60%20%5B%5B2%5D%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py%23L279-L302%29%3A%0A%0A%60%60%60python%0A%40staticmethod%0Adef%20add_watermark%28img_bytes%3A%20bytes%29%20-%3E%20bytes%3A%0A%20%20%20%20from%20PIL%20import%20ImageDraw%2C%20ImageFont%0A%20%20%20%20img%20%3D%20Image.open%28BytesIO%28img_bytes%29%29%0A%20%20%20%20draw%20%3D%20ImageDraw.Draw%28img%29%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20font%20%3D%20ImageFont.truetype%28%22Arial.ttf%22%2C%2020
 %29%0A%20%20%20%20except%20OSError%3A%0A%20%20%20%20%20%20%20%20font%20%3D%20ImageFont.load_default%28%29%0A%20%20%20%20draw.text%28%2810%2C%20img.height%20-%2030%29%2C%20%22Powered%20by%20xyz%22%2C%20fill%3D%22gray%22%2C%20font%3Dfont%29%0A%20%20%20%20output%20%3D%20BytesIO%28%29%0A%20%20%20%20img.save%28output%2C%20format%3D%22PNG%22%29%0A%20%20%20%20return%20output.getvalue%28%29%0A%60%60%60%0A%0A%2A%2AOption%202%20%E2%80%94%20Inside%20%60resize_image%28%29%60%2C%20after%20the%20resize%20on%20line%20296%2A%2A%0A%0AIf%20you%20only%20want%20to%20watermark%20thumbnails%20%28not%20full-size%20screenshots%29%2C%20insert%20it%20inside%20%60resize_image%28%29%60%20between%20line%20296%20and%20297%20%5B%5B3%5D%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py%23L296-L302%29%3A%0A%0A%60%60%60python%0A%20%20%20%20img%20%3D%20img.resize%28thumb_size%2C%20Image.Resampling.LANCZOS%29%0A%20%20%20%20%0A%20%20%20%20%23%20%E2%9C%
 85%20ADD%20WATERMARK%20HERE%0A%20%20%20%20draw%20%3D%20ImageDraw.Draw%28img%29%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20font%20%3D%20ImageFont.truetype%28%22Arial.ttf%22%2C%2020%29%0A%20%20%20%20except%20OSError%3A%0A%20%20%20%20%20%20%20%20font%20%3D%20ImageFont.load_default%28%29%0A%20%20%20%20draw.text%28%2810%2C%20img.height%20-%2030%29%2C%20%22Powered%20by%20xyz%22%2C%20fill%3D%22gray%22%2C%20font%3Dfont%29%0A%20%20%20%20%0A%20%20%20%20new_img%20%3D%20BytesIO%28%29%0A%60%60%60%0A%0A%2A%2AImportant%20caveat%3A%2A%2A%20Note%20that%20%60resize_image%28%29%60%20is%20only%20called%20when%20%60window_size%20%21%3D%20thumb_size%60%20%5B%5B4%5D%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py%23L263-L265%29.%20If%20they%27re%20equal%2C%20%60resize_image%28%29%60%20is%20skipped%20entirely%2C%20so%20the%20watermark%20wouldn%27t%20be%20applied.%20That%27s%20why%20%2A%2AOption%201%20is%20recommended%2A%2A%20%E2%80%9
 4%20it%20catches%20all%20screenshots%20regardless.%0A%0ABoth%20%60ChartScreenshot%60%20and%20%60DashboardScreenshot%60%20inherit%20from%20%60BaseScreenshot%60%20%5B%5B5%5D%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py%23L305-L363%29%2C%20so%20your%20watermark%20will%20apply%20to%20both%20chart%20and%20dashboard%20exports%20automatically.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/discussions/39323)

GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16542016

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "dosubot[bot] (via GitHub)" <gi...@apache.org>.
GitHub user dosubot[bot] added a comment to the discussion: BRANDING ON DOWNLOADED IMAGES

<!-- Answer -->
You've reached the anonymous usage limit of `10` interactions per month. Your usage will reset on `2026-05-01`. If you'd like to use Dosu before then, please [register](https://app.dosu.dev/login?referrer=from-anonymous-rate-limit) to increase your limit to `100` interactions per month for free.


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=brand-link).*

---
<sup>How did I do? [Good](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-great_response#message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda&feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-irrelevant_answer#message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda&feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-incorrect_sources#message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda&feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-too_verbose#message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda&feedback_type=too_verbose) | [Hallucination](https://app
 .dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-hallucination#message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda&feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-bug_report#message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda&feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=feedback-other#message_id=1a4f26db-9785-4c3f-831f-c320ee2b5dda&feedback_type=other)</sup>
[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=chat-badge)&nbsp;[![Open in Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=You%27ve%20reached%20the%20anonymous%20usage%20limit%20of%20%6010%60%20interactions%20per%20month.%20Your%20usage%20will%20reset%20on%20%602026-05-01%60.%20If%20you%27d%20like%20to%20use%20Dosu%20before%20then%2C%20please%20%5Bregister%5D%28https%3A//app.dosu.dev/login%3Freferrer%3Dfrom-anonymous-rate-limit%29%20to%20increase%20your%20limit%20to%20%60100%60%20interactions%20per%20month%20for%20free.)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-assistant&utm_content=join-discord)&nbsp;[![Share on X](https://img.shields.io/badge/X-
 share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/discussions/39323)

GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16543052

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "dosubot[bot] (via GitHub)" <gi...@apache.org>.
GitHub user dosubot[bot] edited a comment on the discussion: BRANDING ON DOWNLOADED IMAGES

<!-- Answer -->
In `superset/utils/screenshots.py`, there are **two places** you should consider, depending on what you want to watermark:

**Option 1 (Recommended) — In `compute_and_cache()`, after the screenshot is captured but before caching (around line 270)**

This is the best spot because it watermarks the **full-resolution** image before any resizing for thumbnails. Insert your watermark call right after the `resize_image` block and before the cache update [[1]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L259-L275):

```python
        # line 259
        image = self.get_screenshot(user=user, window_size=window_size)
    except Exception as ex:
        logger.warning("Failed at generating thumbnail %s", ex, exc_info=True)
        cache_payload.error()
    if image and window_size != thumb_size:
        try:
            image = self.resize_image(image, thumb_size=thumb_size)
        except Exception as ex:
            logger.warning("Failed at resizing thumbnail %s", ex, exc_info=True)
            cache_payload.error()
            image = None

    # ✅ ADD WATERMARK HERE (after line 269, before line 271)
    if image:
        image = self.add_watermark(image)

    if image:
        logger.info("Caching thumbnail: %s", cache_key)
```

Then add this as a static/class method on `BaseScreenshot` [[2]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L279-L302):

```python
@staticmethod
def add_watermark(img_bytes: bytes) -> bytes:
    from PIL import ImageDraw, ImageFont
    img = Image.open(BytesIO(img_bytes))
    draw = ImageDraw.Draw(img)
    try:
        font = ImageFont.truetype("Arial.ttf", 20)
    except OSError:
        font = ImageFont.load_default()
    draw.text((10, img.height - 30), "Powered by xyz", fill="gray", font=font)
    output = BytesIO()
    img.save(output, format="PNG")
    return output.getvalue()
```

**Option 2 — Inside `resize_image()`, after the resize on line 296**

If you only want to watermark thumbnails (not full-size screenshots), insert it inside `resize_image()` between line 296 and 297 [[3]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L296-L302):

```python
    img = img.resize(thumb_size, Image.Resampling.LANCZOS)
    
    # ✅ ADD WATERMARK HERE
    draw = ImageDraw.Draw(img)
    try:
        font = ImageFont.truetype("Arial.ttf", 20)
    except OSError:
        font = ImageFont.load_default()
    draw.text((10, img.height - 30), "Powered by xyz", fill="gray", font=font)
    
    new_img = BytesIO()
```

**Important caveat:** Note that `resize_image()` is only called when `window_size != thumb_size` [[4]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L263-L265). If they're equal, `resize_image()` is skipped entirely, so the watermark wouldn't be applied. That's why **Option 1 is recommended** — it catches all screenshots regardless.

Both `ChartScreenshot` and `DashboardScreenshot` inherit from `BaseScreenshot` [[5]](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/utils/screenshots.py#L305-L363), so your watermark will apply to both chart and dashboard exports automatically.


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=reply-with-mention&utm_term=apache%2Fsuperset).*

---

Share context across your team and agents. Try [Dosu](https://dosu.dev?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-tagline&utm_term=apache%2Fsuperset).

[![Leave Feedback](https://img.shields.io/badge/Leave%20Feedback-555555?style=flat)](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-feedback&utm_term=apache%2Fsuperset&message_id=6a52d105-ef16-4a63-8cf9-f6c12704c492) [![Learn about superset with Dosu](https://img.shields.io/badge/Learn%20about%20superset%20with%20Dosu-2f7b3f?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iODYiIGhlaWdodD0iODkiIHZpZXdCb3g9IjAgMCA4NiA4OSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNS4yOTIzNiAxMi43OTI4TDE3Ljc1OTMgNi42ODE4OFY3Mi41NjY3TDUuMjkyMzYgODQuMDYxOFYxMi43OTI4WiIgZmlsbD0iI0I0QkI5MSIvPjxwYXRoIGQ9Ik0xOC4yNTc1IDczLjExOTZMNTkuMTMyOSA3Mi43NDhMNTEuNzAxMSA4Mi40MDk1TDI5LjAzMzggODYuMjkxTDYuMjM5NjIgODUuMTU1NEwxOC4yNTc1IDczLjExOTZaIiBmaWxsPSIjNzc4NTYxIi8%2BPHBhdGggZD0iTTE3LjQ5MTYgMy43MzYzM0wzLjU4NTU3IDEyLjcwOTlWODMuNTc5MkMzLjU4NTU3IDg0Ljc1NDIgNC4
 5ODU2MyA4NS4zNjUyIDUuODQ3MDUgODQuNTY2TDE5LjYyOTYgNzEuNzgwMSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSI2LjQyODQ0IiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48bWFzayBpZD0iZG9zdS1kLWN1dG91dCIgZmlsbD0id2hpdGUiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNDAuNzA0IDAuNTE4MDY2SDE3LjA0MzlWNzYuMjIyMUg0MC43MDRINDIuNTgwNUg0Ny44MDEzQzY4LjcwNjQgNzYuMjIyMSA4NS42NTMzIDU5LjI3NTIgODUuNjUzMyAzOC4zNzAxQzg1LjY1MzMgMTcuNDY1IDY4LjcwNjMgMC41MTgwNjYgNDcuODAxMyAwLjUxODA2Nkg0Mi41ODA1SDQwLjcwNFoiLz48L21hc2s%2BPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MC43MDQgMC41MTgwNjZIMTcuMDQzOVY3Ni4yMjIxSDQwLjcwNEg0Mi41ODA1SDQ3LjgwMTNDNjguNzA2NCA3Ni4yMjIxIDg1LjY1MzMgNTkuMjc1MiA4NS42NTMzIDM4LjM3MDFDODUuNjUzMyAxNy40NjUgNjguNzA2MyAwLjUxODA2NiA0Ny44MDEzIDAuNTE4MDY2SDQyLjU4MDVINDAuNzA0WiIgZmlsbD0iI0YzRjZGMSIvPjxwYXRoIGQ9Ik0xNy4wNDM5IDAuNTE4MDY2Vi02LjU3OTE5SDkuOTQ2NjlWMC41MTgwNjZIMTcuMDQzOVpNMTcuMDQzOSA3Ni4yMjIxSDkuOTQ2NjlWODMuMzE5NEgxNy4wNDM5Vjc2LjIyMjFaTTE3LjA0MzkgNy42MTUzMkg0MC43MDRWLTYuNT
 c5MTlIMTcuMDQzOVY3LjYxNTMyWk0yNC4xNDEyIDc2LjIyMjFWMC41MTgwNjZIOS45NDY2OVY3Ni4yMjIxSDI0LjE0MTJaTTQwLjcwNCA2OS4xMjQ5SDE3LjA0MzlWODMuMzE5NEg0MC43MDRWNjkuMTI0OVpNNDIuNTgwNSA2OS4xMjQ5SDQwLjcwNFY4My4zMTk0SDQyLjU4MDVWNjkuMTI0OVpNNDcuODAxMyA2OS4xMjQ5SDQyLjU4MDVWODMuMzE5NEg0Ny44MDEzVjY5LjEyNDlaTTc4LjU1NiAzOC4zNzAxQzc4LjU1NiA1NS4zNTU1IDY0Ljc4NjcgNjkuMTI0OSA0Ny44MDEzIDY5LjEyNDlWODMuMzE5NEM3Mi42MjYxIDgzLjMxOTQgOTIuNzUwNSA2My4xOTQ5IDkyLjc1MDUgMzguMzcwMUg3OC41NTZaTTQ3LjgwMTMgNy42MTUzMkM2NC43ODY2IDcuNjE1MzIgNzguNTU2IDIxLjM4NDcgNzguNTU2IDM4LjM3MDFIOTIuNzUwNUM5Mi43NTA1IDEzLjU0NTMgNzIuNjI2IC02LjU3OTE5IDQ3LjgwMTMgLTYuNTc5MTlWNy42MTUzMlpNNDIuNTgwNSA3LjYxNTMySDQ3LjgwMTNWLTYuNTc5MTlINDIuNTgwNVY3LjYxNTMyWk00MC43MDQgNy42MTUzMkg0Mi41ODA1Vi02LjU3OTE5SDQwLjcwNFY3LjYxNTMyWiIgZmlsbD0iYmxhY2siIG1hc2s9InVybCgjZG9zdS1kLWN1dG91dCkiLz48cGF0aCBkPSJNNjguOTIxNSAzNi4wMTM1QzY4LjkyMTUgMzYuMDEzNSA2NS43MzY5IDQ5LjQ3MzggNTEuNDIzMSA0OS40NzM4QzM3LjEwOTMgNDkuNDczOCAzMi41Nzg3IDM3LjM1OTYgMzIuNTc4NyAzNi4wMTM1IiBzdHJva2U9ImJsYWNrIiB
 zdHJva2Utd2lkdGg9IjcuNjkxNjEiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0wLjM0ODYzMyA4NS40OTQ2QzAuMzQ4NjMzIDg1LjQ5NDYgMjkuNDg1NiA4NS44MzA5IDM0LjgwOSA4NS42OThDNDQuODMzNyA4NS40NDc3IDUxLjI4NzIgODQuNDAyIDU3LjUyNjkgNzguOTcyNEM2Mi44MTI5IDc0LjM3MjcgNzUuMTM0MiA1OS42ODM2IDc1LjEzNDIgNTkuNjgzNiIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSI2LjE2NDgyIi8%2BPC9zdmc%2B)](https://github.dosu.com/apache/superset?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-learn-repo&utm_term=apache%2Fsuperset) [![Add Dosu to your team](https://img.shields.io/badge/Add%20Dosu%20to%20your%20team-1f6feb?style=flat)](https://app.dosu.dev/signup?referrer=openSource&source=github-footer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-add-team&utm_term=apache%2Fsuperset)

GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16542016

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [D] BRANDING ON DOWNLOADED IMAGES [superset]

Posted by "srijani-smsrc (via GitHub)" <gi...@apache.org>.
GitHub user srijani-smsrc added a comment to the discussion: BRANDING ON DOWNLOADED IMAGES

def add_watermark(image_bytes):
    img = Image.open(BytesIO(image_bytes))
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("Arial.ttf", 20)
    draw.text((10, img.height - 30), "Powered by xyz", fill="gray", font=font)
    output = BytesIO()
    img.save(output, format="PNG")
    return output.getvalue()
    
    
    exactly where to add this in the screenshots file in superset5

@dosubot

GitHub link: https://github.com/apache/superset/discussions/39323#discussioncomment-16541996

----
This is an automatically sent email for notifications@superset.apache.org.
To unsubscribe, please send an email to: notifications-unsubscribe@superset.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org