Fastest dithering / halftoning library in C

假如想象 提交于 2019-12-05 10:08:04

Dithering is going to take quite a bit of time depending on the algorithm chosen.

It's fairly trivial to implement Bayer (Matrix) and Floyd-Steinberg (Diffusion) dithering.

Bayer filtering can be made extremely fast when coded with with MMX/SSE to process parallel pixels. You may also be able to do the dithering / conversion using a GPU shader.

FWIW, you're already using GraphicsMagick but there's an entire list of OSS graphics libraries here

From the list provided by Adisak, without any testing, I would bet on AfterImage. The Afterstep people are obsessed with speed, and also described a clever algorithm.

You could take an alternative approach, if your server could be equipped with a decent PCI-express graphics card featuring OpenGL. Here are some specs from Nvidia. Search for "index mode". What you could do is select a 16 or 256 color display mode, render your image as a texture on a flat polygon (like the side of cube) and then read the frame back.

When reading a frame from an OpenGL card, it is important that bandwidth is good from the card, hence the need for PCI-express. As the documentation says, you also have to choose your colors in indexed mode for decent effects.

I know it's not a C library, but this got me curious about what's available for .NET to do error-diffusion which I used some 20 years ago on a project. I found this and specifically this method.

But to try be helpful :) I found this C library.

Here is an implementation of the Floyd-Steinberg method for half-toning:

#include <opencv2/opencv.hpp>

using namespace cv;

int main(){

uchar scale = 128; // change this parameter to 8, 32, 64, 128 to change the dot size
Mat img = imread("../halftone/tom.jpg", CV_LOAD_IMAGE_GRAYSCALE);
for (int r=1; r<img.rows-1; r++) {
    for (int c=1; c<img.cols-1; c++) {
        uchar oldPixel = img.at<uchar>(r,c);
        uchar newPixel = oldPixel / scale * scale;
        img.at<uchar>(r,c) = newPixel;
        int quantError = oldPixel - newPixel;
        img.at<uchar>(r+1,c)   +=  7./16. * quantError;
        img.at<uchar>(r-1,c+1) +=  3./16. * quantError;
        img.at<uchar>(r,c+1) +=  5./16. * quantError;
        img.at<uchar>(r+1,c+1) +=  1./16. * quantError;
    }
}
imshow("halftone", img);
waitKey();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!