Eir
Eir

Reputation: 1115

Dither a photo for monochrome display (Android)

I'm drawing contact pictures on a monochrome display, but the results are poor, obviously only threshold dithering is applied (see comparisons here: dithering algorithms). How can I achieve the ordered or the other (better) dithering results?

Here's the code I use:

// RGB_565 is most suitable for monochrome display
Bitmap b = Bitmap.createBitmap(desW, desH, Bitmap.Config.RGB_565);
// Set the density to default to avoid scaling.
b.setDensity(DisplayMetrics.DENSITY_DEFAULT);
Canvas c = new Canvas(b);
c.drawBitmap(photo, source, destination, new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG));

I tried setting different bitmap configurations, but doesn't change anything.

Upvotes: 0

Views: 801

Answers (1)

Eir
Eir

Reputation: 1115

Ok, here's the answer that worked for me: How to convert a 24 Bit PNG to 3 Bit PNG using Floyd–Steinberg dithering?

I just replaced the BufferedImage with a Bitmap, the call to method getRGB(x, y) with getPixel(x,y), and the helper class implementation to this:

  static class C3 {
    int r, g, b;

    public C3(int c) {
      this.r = Color.red(r);
      this.g = Color.green(c);
      this.b = Color.blue(c);
    }
    public C3(int r, int g, int b) {
      this.r = r;
      this.g = g;
      this.b = b;
    }

    public C3 add(C3 o) {
      return new C3(r + o.r, g + o.g, b + o.b);
    }
    public C3 sub(C3 o) {
      return new C3(r - o.r, g - o.g, b - o.b);
    }
    public C3 mul(double d) {
      return new C3((int) (d * r), (int) (d * g), (int) (d * b));
    }
    public int diff(C3 o) {
      return Math.abs(r - o.r) +  Math.abs(g - o.g) +  Math.abs(b - o.b);
    }

    public int toRGB() {
      return Color.rgb(clamp(r), clamp(g), clamp(b));
    }
    public int clamp(int c) {
      return Math.max(0, Math.min(255, c));
    }
  }

Upvotes: 3

Related Questions