← All articles 7 min read

Image to Pixel Art: 5 Methods to Pixelate Any Photo

Pixel art reduces an image to a grid of visible, uniformly colored squares. Each "pixel" in the art is much larger than a screen pixel — typically 4×4 to 32×32 actual pixels. The style originated from hardware constraints in early video games and has become a deliberate aesthetic choice in game design, NFT collections, social media avatars, and retro-inspired graphics.

Converting a photo to pixel art involves three steps: downscale the image to a very small resolution, reduce the color palette, and upscale back to display size with nearest-neighbor interpolation (no smoothing). The result trades photographic detail for blocky charm.

If you need to resize an image before starting, Pixotter handles it instantly in the browser.


How Photo-to-Pixel-Art Conversion Works

The algorithm behind every method below follows the same logic:

  1. Downscale. Shrink the image to your target grid size (e.g., 64×64 or 128×128 pixels). This is the step that creates the pixelated look — averaging many source pixels into single grid cells.

  2. Reduce the color palette. Real photos use thousands of colors. Pixel art typically uses 8-64 colors. Quantization algorithms (median cut, k-means, octree) select the most representative colors and remap every pixel.

  3. Upscale with nearest-neighbor. Scale the tiny image back to display resolution (e.g., 512×512 or 1024×1024) using nearest-neighbor interpolation. This preserves the hard pixel edges — bilinear or bicubic interpolation would blur them away.

The grid size determines how much detail survives. A 32×32 grid produces abstract, icon-like results. A 128×128 grid retains recognizable features and fine details.


Method 1: Photoshop (v26.3)

Photoshop gives you fine control over downscaling method, color reduction, and upscaling interpolation.

Steps

  1. Open your image in Photoshop v26.3.
  2. Downscale: Go to Image → Image Size. Set the width to your target grid size (64px for a classic look, 128px for more detail). Set Resample to Nearest Neighbor (hard edges). Click OK.
  3. Reduce colors (optional): Go to Image → Mode → Indexed Color. Set Colors to your target palette (16-64). Set Dither to None for clean pixel blocks. Click OK. Convert back: Image → Mode → RGB Color.
  4. Upscale: Go to Image → Image Size. Set width to your display size (512px, 1024px, etc.). Set Resample to Nearest Neighbor (hard edges). Click OK.

Critical: Both the downscale and upscale must use Nearest Neighbor. If you accidentally use Bicubic (the default), the pixel edges get smoothed into gradients and the pixel art look is destroyed.

Automating With Actions

Record the three-step process as a Photoshop Action. Then use File → Automate → Batch to convert an entire folder. This is the fastest way to process dozens of photos without writing code.


Method 2: GIMP (v2.10.38) — Free

GIMP handles the same workflow with equivalent quality. It uses the term "None" for nearest-neighbor interpolation.

Steps

  1. Open your image in GIMP v2.10.38.
  2. Downscale: Image → Scale Image. Set width to your grid size (e.g., 64px). Set Interpolation to None. Click Scale.
  3. Reduce colors: Image → Mode → Indexed. Choose Generate optimum palette with your target color count (16-64). Set Color dithering to None. Click Convert.
  4. Convert back: Image → Mode → RGB.
  5. Upscale: Image → Scale Image. Set width to display size. Interpolation: None. Click Scale.
  6. Export: File → Export As → PNG.

GIMP's indexed color quantization is effective for simple images. For photos with complex gradients, the palette reduction can introduce banding — reduce to 32-64 colors instead of 16 to mitigate this.

License: GIMP is free under GPL-3.0. G'MIC plugin (CeCILL-C license) adds additional pixelation filters if you want more creative options.


Method 3: Aseprite (v1.3.7) — Purpose-Built

Aseprite is a dedicated pixel art editor designed for sprite creation and animation. It is not a photo editor, but it handles photo-to-pixel conversion well because its entire rendering pipeline is built for pixel-perfect output.

Steps

  1. Open Aseprite v1.3.7.
  2. Import: File → Open and select your photo.
  3. Resize: Sprite → Sprite Size. Set width to your grid size. Choose Nearest Neighbor. Click OK.
  4. Reduce palette: Sprite → Color Mode → Indexed. Set the number of colors. Aseprite uses the RGBA → Indexed conversion with optional dithering.
  5. Manual cleanup: This is where Aseprite shines. Use the pencil tool (pixel-perfect mode enabled) to hand-edit individual pixels. Fix areas where the auto-conversion lost important details.
  6. Export: File → Export as PNG. Aseprite can also export sprite sheets for game engines.

The manual cleanup step is what separates good pixel art from a filter. Automated conversion gets you 80% of the way — fixing eyes, edges, and key details by hand takes it to 100%.

Cost: Aseprite is $19.99 (one-time). The source code is available on GitHub under a proprietary license — you can compile it yourself for free, but the compiled version is paid.


Method 4: Python + Pillow (v10.3.0)

The most flexible approach for batch processing or integration into a pipeline.

from PIL import Image  # Pillow 10.3.0

def photo_to_pixel_art(
    input_path: str,
    output_path: str,
    grid_size: int = 64,
    num_colors: int = 32,
    scale: int = 8,
) -> None:
    img = Image.open(input_path).convert("RGB")

    # Step 1: Downscale with nearest-neighbor
    aspect = img.height / img.width
    small = img.resize(
        (grid_size, int(grid_size * aspect)),
        Image.Resampling.NEAREST,
    )

    # Step 2: Reduce color palette
    indexed = small.quantize(colors=num_colors, method=Image.Quantize.MEDIANCUT)
    small_rgb = indexed.convert("RGB")

    # Step 3: Upscale with nearest-neighbor
    final = small_rgb.resize(
        (grid_size * scale, int(grid_size * aspect) * scale),
        Image.Resampling.NEAREST,
    )
    final.save(output_path)

photo_to_pixel_art("photo.jpg", "pixel-art.png", grid_size=64, num_colors=24)

Batch Processing

from pathlib import Path

input_dir = Path("photos")
output_dir = Path("pixel-art")
output_dir.mkdir(exist_ok=True)

for img_path in input_dir.glob("*.jpg"):
    photo_to_pixel_art(
        str(img_path),
        str(output_dir / f"{img_path.stem}-pixel.png"),
        grid_size=96,
        num_colors=32,
    )

Tuning Parameters

Parameter Low Value High Value Effect
grid_size 32 256 Fewer pixels → more abstract; more pixels → more detailed
num_colors 8 64 Fewer → bold, graphic; more → subtle gradients preserved
scale 4 16 Controls final output resolution (grid_size × scale)

Method 5: Online Tools (No Install)

For one-off conversions without installing anything:

Tool Grid Control Palette Control Export Watermark
Pixelator (pixelator.co) Slider (8-256) Auto only PNG No
Pixel Art Converter (pixelicious.kdex.de) Slider 8-64 colors PNG No
Lunapic Preset sizes No PNG/JPG No

Online tools are convenient for single images but lack batch processing and fine-tuning. For ongoing work, use the Photoshop/GIMP/Python methods above.

After converting, run your pixel art through Pixotter's compressor to optimize the PNG file size without affecting quality — pixel art compresses extremely well because of the limited color palette and uniform blocks.


Choosing the Right Grid Size

Use Case Recommended Grid Colors Style
Social media avatar / icon 32×32 — 64×64 8-16 Abstract, iconic
Character sprite (game) 16×16 — 64×64 16-32 Clean, readable
Portrait / profile art 96×96 — 128×128 24-48 Recognizable features
Landscape / scene 128×128 — 256×256 32-64 Detailed, scenic
Print / poster 256×256+ 48-64 Maximum detail

Tips for Better Results

Start with high contrast. Photos with strong lighting and clear subjects convert better than flat, evenly lit images. Adjust contrast and brightness before pixelating — either in your editor or using Pixotter's image tools.

Choose your color palette intentionally. Auto-quantization works, but curated palettes look better. Classic pixel art palettes (PICO-8's 16 colors, Endesga 32, Lospec DB32) are specifically designed for pixel art aesthetics. In Aseprite or GIMP, you can load a custom palette before indexing.

Clean up key features. Eyes, mouths, and distinctive shapes often need manual pixel adjustment. One misplaced pixel in a 32×32 face changes the entire expression.

Export as PNG, never JPEG. JPEG compression introduces artifacts around the hard pixel edges, creating visible smudging. PNG preserves the exact pixel grid. For pixel art specifically, PNG files are also smaller because the limited palette and uniform blocks compress efficiently with PNG's deflate algorithm.


FAQ

What resolution should my source photo be? Any resolution works — the downscaling step handles it. Higher-resolution sources give better results at larger grid sizes (128+) because there is more detail to sample from. For 32×32 or 64×64 grids, even a phone photo is fine.

Can I convert pixel art back to a photo? No. Pixel art is a lossy reduction — the original color and detail information is permanently discarded during downscaling and palette reduction. Keep your source photo if you might need it later.

What is the difference between pixelating and making pixel art? Pixelating applies a mosaic filter that averages blocks of pixels. Making pixel art goes further: it reduces the color palette, sharpens edges, and ideally includes manual cleanup. Pixelation is step 1 of 3.

Which grid size looks best for social media? 64×64 is the sweet spot for avatars and profile images. It is recognizable at thumbnail size while maintaining the pixel art aesthetic. Scale up to 512×512 or 1024×1024 for the final export.

Does Pixotter have a pixel art tool? Pixotter focuses on image conversion and optimization. You can resize source images to exact pixel dimensions before feeding them into a pixel art workflow, and compress the final PNG output for web use.

Is there a difference between nearest-neighbor and point sampling? No — they are different names for the same algorithm. Photoshop calls it "Nearest Neighbor (hard edges)." Other tools call it "Point" or "None." All preserve pixel-sharp edges by copying the closest pixel value instead of interpolating between neighbors.