How to convert a 24 Bit PNG to 3 Bit PNG using Floyd–Steinberg dithering?

前端 未结 4 1843
予麋鹿
予麋鹿 2020-12-16 18:11

How to convert a 24 Bit PNG to 3 Bit PNG using Floyd–Steinberg dithering? java.awt.image.BufferedImage should be used to get and set RGB values.

On wik

4条回答
  •  臣服心动
    2020-12-16 18:50

    Use image.getRGB(x, y) and image.setRGB(x, y, color) and use the pseudocode from the wikipedia article. Note that code on the wiki does not say how to "subtract", "add" and "multiply" colors. (The T3 class below handles "color" manipulation.)

    The code below will produce this screenshot:

    screenshot

    class Test {
      private static BufferedImage floydSteinbergDithering(BufferedImage img) {
    
        C3[] palette = new C3[] {
            new C3(  0,   0,   0),
            new C3(  0,   0, 255),
            new C3(  0, 255,   0),
            new C3(  0, 255, 255),
            new C3(255,   0,   0),
            new C3(255,   0, 255),
            new C3(255, 255,   0),
            new C3(255, 255, 255)
        };
    
        int w = img.getWidth();
        int h = img.getHeight();
    
        C3[][] d = new C3[h][w];
    
        for (int y = 0; y < h; y++) 
          for (int x = 0; x < w; x++) 
            d[y][x] = new C3(img.getRGB(x, y));
    
        for (int y = 0; y < img.getHeight(); y++) {
          for (int x = 0; x < img.getWidth(); x++) {
    
            C3 oldColor = d[y][x];
            C3 newColor = findClosestPaletteColor(oldColor, palette);
            img.setRGB(x, y, newColor.toColor().getRGB());
    
            C3 err = oldColor.sub(newColor);
    
            if (x+1 < w)         d[y  ][x+1] = d[y  ][x+1].add(err.mul(7./16));
            if (x-1>=0 && y+1

提交回复
热议问题