79664989

Date: 2025-06-13 14:24:05
Score: 0.5
Natty:
Report link

I have found a workaround to display the image sharp.
It requires manually changing a value in the code each time you change scaling in Windows.

Step 1:

%%javascript
const ratio = window.devicePixelRatio;
alert("devicePixelRatio: " + ratio);

notification popup showing a devicePixelRatio  of 1.875

Step 2:

devicePixelRatio = 1.875 # manually enter the value that was shown

Step 3:

from PIL import Image
from IPython.display import HTML
import numpy as np
import io
import base64

# 32x32 data
bw_data = np.zeros((32,32),dtype=np.uint8)
# (odd_rows, even_columns)
bw_data[1::2,::2] = 1
# (even_rows, odd_columns)
bw_data[::2,1::2] = 1

# Build pixel-exact HTML
def display_pixel_image(np_array):
    # Convert binary image to black & white PIL image
    img = Image.fromarray(np_array * 255).convert('1')
    
    # Convert to base64-encoded PNG
    buf = io.BytesIO()
    img.save(buf, format='PNG')
    b64 = base64.b64encode(buf.getvalue()).decode('utf-8')
    
    # HTML + CSS to counteract scaling
    html = f"""
    <style>
      .pixel-art {{
        width: calc({img.width}px / {devicePixelRatio});
        image-rendering: pixelated;
        display: block;
        margin: 0;
        padding: 0;
      }}
    </style>
    <img class="pixel-art" src="data:image/png;base64,{b64}">
    """
    display(HTML(html))

display_pixel_image(bw_data)

output:

sharp image

Visual Studio Code cannot access ipython kernel so I don't know how to retrieve devicePixelRatio from Javascript. I tried to make an ipython widget, but was not able to refresh it automatically. If this can be done automatically then it won't require user input.

Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: elechris