Skip to main content
refactored code
Source Link
root
  • 111
  • 3
import numpy as np
import matplotlib.pyplot as plt

def subpixel_render_and_save_all(image_path):
    # Load the image as an array and normalize to RGB values [0, 255]
    img_arrayimg = plt.imread(image_path)
    
    # HandleIgnore imagesalpha withchannel anfor alphanow. channelTODO ifhandle presentalpha channel
    if img_arrayimg.shape[2] == 4:
        img_arrayimg = img_array[img[:, :, :3]
    img_array
    img = (img_arrayimg * 255).astype(np.uint8)
    
    height, width, _ = img_arrayimg.shape

    # Create a base for the subpixel-rendered image (3x larger dimensions)
    subpixel_arrayimg_subpixels = np.zeros((height * 3, width * 3, 3), dtype=np.uint8)

    # Place each color channel in its respective vertical subpixel column
    subpixel_array[img_subpixels[:, 0::3, 0] = np.repeat(img_array[img[:, :, 0], 3, axis=0)  # Red
    subpixel_array[img_subpixels[:, 1::3, 1] = np.repeat(img_array[img[:, :, 1], 3, axis=0)  # Green
    subpixel_array[img_subpixels[:, 2::3, 2] = np.repeat(img_array[img[:, :, 2], 3, axis=0)  # Blue
 
    # Derive output file names
    base_filename = image_path.rsplit('.', 1)[0]
    colorful_output_path = f"{base_filename}_subpixel.png"
    grayscale_output_path = f"{base_filename}_subpixel_grayscale.png"
    downscaled_output_path = f"{base_filename}_subpixel_grayscale_downscaled.png"

    # Save the colorful subpixel-rendered image
    plt.imsave(colorful_output_path, subpixel_array)
    print(f"Colorful subpixel-rendered image saved to {colorful_output_path}")

    # Convert to grayscale using luminance method
    # grayscale_subpixel_arrayimg_subpixels_grayscale = (0.2989 * subpixel_array[img_subpixels[:, :, 0] +
                                # 0.5870 * subpixel_array[img_subpixels[:, :, 1] +
                                # 0.1140 * subpixel_array[img_subpixels[:, :, 2]).astype(np.uint8)

    # Convert to grayscale
    grayscale_subpixel_arrayimg_subpixels_grayscale = (subpixel_array[img_subpixels[:, :, 0] +
                                subpixel_array[img_subpixels[:, :, 1] +
                                subpixel_array[img_subpixels[:, :, 2]).astype(np.uint8)

    # Save the grayscale subpixel-rendered image
    plt.imsave(grayscale_output_path, grayscale_subpixel_array, cmap="gray")
    print(f"Grayscale subpixel-rendered image saved to {grayscale_output_path}")

    # Downscale by averaging each 3x3 block to a single pixel
    downscaled_arrayimg_subpixels_grayscale_downscaled = grayscale_subpixel_arrayimg_subpixels_grayscale.reshape(height, 3, width, 3).mean(axis=(1, 3)).astype(np.uint8)

    # Save thebase_filename downscaled= grayscaleimage_path.rsplit('.', image1)[0]
    plt.imsave(downscaled_output_path, downscaled_arrayf"{base_filename}_subpixels.png", cmap="gray"img_subpixels)
    printplt.imsave(f"Downscaledf"{base_filename}_subpixels_grayscale.png", grayscaleimg_subpixels_grayscale, imagecmap="gray")
 saved to  plt.imsave(f"{downscaled_output_pathbase_filename}"_subpixels_grayscale_downscaled.png", img_subpixels_grayscale_downscaled, cmap="gray")

# Example usage
subpixel_render_and_save_all("input_image.png")

import numpy as np
import matplotlib.pyplot as plt

def subpixel_render_and_save_all(image_path):
    # Load the image as an array and normalize to RGB values [0, 255]
    img_array = plt.imread(image_path)
    
    # Handle images with an alpha channel if present
    if img_array.shape[2] == 4:
        img_array = img_array[:, :, :3]
    img_array = (img_array * 255).astype(np.uint8)
    
    height, width, _ = img_array.shape

    # Create a base for the subpixel-rendered image (3x larger dimensions)
    subpixel_array = np.zeros((height * 3, width * 3, 3), dtype=np.uint8)

    # Place each color channel in its respective vertical subpixel column
    subpixel_array[:, 0::3, 0] = np.repeat(img_array[:, :, 0], 3, axis=0)  # Red
    subpixel_array[:, 1::3, 1] = np.repeat(img_array[:, :, 1], 3, axis=0)  # Green
    subpixel_array[:, 2::3, 2] = np.repeat(img_array[:, :, 2], 3, axis=0)  # Blue
 
    # Derive output file names
    base_filename = image_path.rsplit('.', 1)[0]
    colorful_output_path = f"{base_filename}_subpixel.png"
    grayscale_output_path = f"{base_filename}_subpixel_grayscale.png"
    downscaled_output_path = f"{base_filename}_subpixel_grayscale_downscaled.png"

    # Save the colorful subpixel-rendered image
    plt.imsave(colorful_output_path, subpixel_array)
    print(f"Colorful subpixel-rendered image saved to {colorful_output_path}")

    # Convert to grayscale using luminance method
    # grayscale_subpixel_array = (0.2989 * subpixel_array[:, :, 0] +
                                # 0.5870 * subpixel_array[:, :, 1] +
                                # 0.1140 * subpixel_array[:, :, 2]).astype(np.uint8)

    # Convert to grayscale
    grayscale_subpixel_array = (subpixel_array[:, :, 0] +
                                subpixel_array[:, :, 1] +
                                subpixel_array[:, :, 2]).astype(np.uint8)

    # Save the grayscale subpixel-rendered image
    plt.imsave(grayscale_output_path, grayscale_subpixel_array, cmap="gray")
    print(f"Grayscale subpixel-rendered image saved to {grayscale_output_path}")

    # Downscale by averaging each 3x3 block to a single pixel
    downscaled_array = grayscale_subpixel_array.reshape(height, 3, width, 3).mean(axis=(1, 3)).astype(np.uint8)

    # Save the downscaled grayscale image
    plt.imsave(downscaled_output_path, downscaled_array, cmap="gray")
    print(f"Downscaled grayscale image saved to {downscaled_output_path}")

# Example usage
subpixel_render_and_save_all("input_image.png")

import numpy as np
import matplotlib.pyplot as plt

def subpixel_render_and_save_all(image_path):
    # Load the image as an array and normalize to RGB values [0, 255]
    img = plt.imread(image_path)
    
    # Ignore alpha channel for now. TODO handle alpha channel
    if img.shape[2] == 4:
        img = img[:, :, :3]
    
    img = (img * 255).astype(np.uint8)
    
    height, width, _ = img.shape

    # Create a base for the subpixel-rendered image (3x larger dimensions)
    img_subpixels = np.zeros((height * 3, width * 3, 3), dtype=np.uint8)

    # Place each color channel in its respective vertical subpixel column
    img_subpixels[:, 0::3, 0] = np.repeat(img[:, :, 0], 3, axis=0)  # Red
    img_subpixels[:, 1::3, 1] = np.repeat(img[:, :, 1], 3, axis=0)  # Green
    img_subpixels[:, 2::3, 2] = np.repeat(img[:, :, 2], 3, axis=0)  # Blue
    
    # Convert to grayscale using luminance method
    # img_subpixels_grayscale = (0.2989 * img_subpixels[:, :, 0] +
                                # 0.5870 * img_subpixels[:, :, 1] +
                                # 0.1140 * img_subpixels[:, :, 2]).astype(np.uint8)

    # Convert to grayscale
    img_subpixels_grayscale = (img_subpixels[:, :, 0] +
                               img_subpixels[:, :, 1] +
                               img_subpixels[:, :, 2]).astype(np.uint8)

    # Downscale by averaging each 3x3 block to a single pixel
    img_subpixels_grayscale_downscaled = img_subpixels_grayscale.reshape(height, 3, width, 3).mean(axis=(1, 3)).astype(np.uint8)

    base_filename = image_path.rsplit('.', 1)[0]
    plt.imsave(f"{base_filename}_subpixels.png", img_subpixels)
    plt.imsave(f"{base_filename}_subpixels_grayscale.png", img_subpixels_grayscale, cmap="gray")
    plt.imsave(f"{base_filename}_subpixels_grayscale_downscaled.png", img_subpixels_grayscale_downscaled, cmap="gray")

# Example usage
subpixel_render_and_save_all("input_image.png")

added 14 characters in body
Source Link
root
  • 111
  • 3

You canBy simulatesimulating what the subpixels look like, and optionally convertconverting that to greyscale to see, we can obtain the intended (even better: color-artifact-free) effect of the original subpixel rendering. The algorithm is described below.

Someone please add this to a screen magnifier software to help read small text and inspect graphic renders.

Results for going from the top left to the bottom right image look nice:

originalgreyscale

      ↓                 ↑

simulated subpixelssimulated subpixels, greyscale

The algorithm is:

Results for going from the top left to the bottom right image look nice:

originalgreyscale

      ↓                 ↑

simulated subpixelssimulated subpixels, greyscale

You can simulate what the subpixels look like, and optionally convert that to greyscale to see the intended color-artifact-free effect of the original subpixel rendering. The algorithm is described below.

Someone please add this to a screen magnifier software to help read small text and inspect graphic renders.

Results for going from the top left to the bottom right image look nice:

originalgreyscale

      ↓                 ↑

simulated subpixelssimulated subpixels, greyscale

By simulating what the subpixels look like, and optionally converting that to greyscale, we can obtain the intended (even better: color-artifact-free) effect of the original subpixel rendering.

Someone please add this to a screen magnifier software to help read small text and inspect graphic renders.

Results for going from the top left to the bottom right image look nice:

originalgreyscale

      ↓                 ↑

simulated subpixelssimulated subpixels, greyscale

The algorithm is:

added 29 characters in body
Source Link
root
  • 111
  • 3

You can simulate what the subpixels look like, and optionally convert that to greyscale to see the intended color-artifact-free effect of the original subpixel rendering. The algorithm is described below.

  • Create an image file that simulates what the screen looks like at 3x magnification, i.e. render each subpixel as three dedicated pixels of only that primary hue (red, green, or blue).
  • Optionally, convert to greyscale (and brighten 3x because the simulated image can't be bright without HDR).
  • Display the result at a high zoom level, otherwise the subpixels of the displaying device would interfere a tiny bit. Compensating for that as well is a different story.

You can simulate what the subpixels look like, and optionally convert that to greyscale to see the intended color-artifact-free effect of the original subpixel rendering.

  • Create an image file that simulates what the screen looks like at 3x magnification, i.e. render each subpixel as three dedicated pixels of only that primary hue (red, green, or blue).
  • Optionally, convert to greyscale (and brighten 3x because the simulated image can't be bright without HDR).
  • Display the result at a high zoom level, otherwise the subpixels of the displaying device would interfere a tiny bit. Compensating for that as well is a different story.

You can simulate what the subpixels look like, and optionally convert that to greyscale to see the intended color-artifact-free effect of the original subpixel rendering. The algorithm is described below.

  • Create an image that simulates what the screen looks like at 3x magnification, i.e. render each subpixel as three dedicated pixels of only that primary hue (red, green, or blue).
  • Optionally, convert to greyscale (and brighten 3x because the simulated image can't be bright without HDR).
  • Display the result at a high zoom level, otherwise the subpixels of the displaying device would interfere a tiny bit. Compensating for that as well is a different story.
added 87 characters in body
Source Link
root
  • 111
  • 3
Loading
deleted 5 characters in body
Source Link
root
  • 111
  • 3
Loading
Source Link
root
  • 111
  • 3
Loading