如何获取颜色参数以传递稀疏颜色?

时间:2017-05-18 14:00:07

标签: c imagemagick magickwand

我一直在努力获得最高饱和度和鲜艳的色彩。 为此,我有以下命令和C程序得到相同的结果。

convert one.jpg -alpha off -scale '50x50!' -depth 8 \
'(' -clone 0 -colorspace HSB -channel gb -separate +channel -threshold 50% -compose multiply -composite ')'\
-alpha off -compose copy_opacity -composite sparse-color:-|\
convert -size 50x50 xc: -sparse-color voronoi @- +dither -colors 6 -depth 8 -format %c histogram:info:

执行了两个命令,因此我将其分开并单独制作。然后我将第一个命令的输出写入文本文件,并在第二个命令中读取该文本文件。请看下面两个命令。

/*First Part*/
convert one.jpg -alpha off -scale '50x50!' -depth 8 '(' -clone 0 -colorspace HSB -channel gb -separate +channel -threshold 50% -compose multiply -composite ')' -alpha off -compose copy_opacity -composite sparse-color:-test.txt

/*Second Part*/
convert -size 50x50 xc: -sparse-color voronoi @-test.txt +dither -colors 6 -depth 8 -format %c histogram:info:  

使用这个我得到了相同的输出。下面是我的C程序实现相同的。在代码中,第一部分已被涵盖。但是我从第一个转换命令和C代码得到的结果是不一样的。我不明白我错过了什么。

#include "MagickWand/studio.h"
#include "MagickWand/MagickWand.h"
void dominantSix(){

    /* convert one.jpg -alpha off -scale '50x50!'\
     -depth 8 '(' -clone 0 -colorspace HSB -channel gb -separate +channel -threshold 50% -compose multiply -composite ')'\
      -alpha off -compose copy_opacity -composite sparse-color:-test.txt */

    MagickWand * wand, * wand0, * wand1;

    PixelIterator * iteration;
    PixelWand ** row;
    PixelInfo pixel;
    size_t x, y, row_width;

    wand = NewMagickWand();
    MagickReadImage(wand, "car.jpg");
    MagickSetImageAlphaChannel(wand, OffAlphaChannel);

    MagickScaleImage(wand, 50, 50);
    MagickSetImageDepth(wand,8);

    wand0 = CloneMagickWand(wand);
    wand1 = CloneMagickWand(wand);

    MagickTransformImageColorspace(wand0, HSBColorspace);
    MagickSetImageChannelMask(wand0, GreenChannel);
    MagickSeparateImage(wand0, GreenChannel);
    MagickThresholdImage(wand0, QuantumRange*50/100);

    MagickTransformImageColorspace(wand1, HSBColorspace);
    MagickSetImageChannelMask(wand1, BlueChannel);
    MagickSeparateImage(wand1, BlueChannel);
    MagickThresholdImage(wand1, QuantumRange*50/100);

    MagickCompositeImage(wand0, wand1, MultiplyCompositeOp, MagickFalse, 0, 0);

    wand1 = DestroyMagickWand(wand1);

    MagickSetImageAlphaChannel(wand, OffAlphaChannel);
    MagickCompositeImage(wand, wand0, CopyAlphaCompositeOp, MagickFalse, 0, 0);

    wand0 = DestroyMagickWand(wand0);


    size_t height = MagickGetImageHeight(wand);
    size_t width = MagickGetImageWidth(wand);

    iteration = NewPixelIterator(wand);
    FILE *fptr;
    fptr = fopen("program.txt", "w");
    for (y = 0; y < height; ++ y)
    {
        row = PixelGetNextIteratorRow(iteration, &row_width);
        for (x = 0; x < row_width; ++x)
        {
            PixelGetMagickColor(row[x], &pixel);
            size_t red = pixel.red*255/QuantumRange;
            size_t green = pixel.green*255/QuantumRange;
            size_t blue = pixel.blue*255/QuantumRange;
            char color[30];
            sprintf(color, "%zu%s%zu%s%s%zu%s%zu%s%zu%s%s", x, ",", y, ",", "srgb(", red, ",", green, ",", blue, ",", "1) ");
            fprintf(fptr,"%s", color);
        }
        PixelSyncIterator(iteration);
    }
    fclose(fptr);

    PixelSyncIterator(iteration);
    iteration = DestroyPixelIterator(iteration);
    wand = DestroyMagickWand(wand);
    MagickWandTerminus();
}

int main(int argc, char const *argv[]) {
  dominantSix();
  return 0;
}

下面是源Image和两个文本文件的链接,一个来自CLI,另一个来自C。

Text file output from C

Text file output from CLI

one.jpg

1 个答案:

答案 0 :(得分:2)

编辑以消除program.txt步骤

如果您已经在撰写,则可以跳过稀疏颜色提取,并将颜色直接应用于MagickSparseColorImage

// ... Omitting first half of function ...
MagickSetImageAlphaChannel(wand, OffAlphaChannel);
MagickCompositeImage(wand, wand0, CopyAlphaCompositeOp, MagickFalse, 0, 0);

wand0 = DestroyMagickWand(wand0);

size_t height = MagickGetImageHeight(wand);
size_t width = MagickGetImageWidth(wand);
size_t spares_index = 0;
// Allocated enough memory to hold Sparse Color data
double * sparse_args = malloc(sizeof(double) * height * width * 5);
// Iterate over pixel data
iteration = NewPixelIterator(wand);
for (y = 0; y < height; ++ y)
{
    row = PixelGetNextIteratorRow(iteration, &row_width);
    for (x = 0; x < row_width; ++x)
    {
        PixelGetMagickColor(row[x], &pixel);
        // Append coord + color data if pixel is visible.
        if (pixel.alpha == QuantumRange) {
            sparse_args[spares_index++] = (double)x;
            sparse_args[spares_index++] = (double)y;
            sparse_args[spares_index++] = pixel.red / QuantumRange;
            sparse_args[spares_index++] = pixel.green / QuantumRange;
            sparse_args[spares_index++] = pixel.blue / QuantumRange;
        }
    }
}
iteration = DestroyPixelIterator(iteration);
wand = DestroyMagickWand(wand);

// Generate new image to apply spares-color data
MagickWand * final;
final = NewMagickWand();
MagickSetSize(final, 50, 50);
MagickReadImage(final, "xc:");
MagickSparseColorImage(final, VoronoiColorInterpolate, spares_index, sparse_args);
MagickQuantizeImage(final, 6, RGBColorspace, 0, NoDitherMethod, MagickFalse);

// Generate Histogram
size_t histogram_size = 0;
PixelWand ** colors = MagickGetImageHistogram(final, &histogram_size);
for (int index = 0; index < histogram_size; ++index) {
    PixelWand * color = colors[index];
    size_t color_count = PixelGetColorCount(color);
    if (color_count) {
        char * color_name = PixelGetColorAsString(color);
        printf("%s => %lu\n", color_name, color_count);
        free(color_name);
    }
}
// Clean-up
free(sparse_args);
colors = DestroyPixelWands(colors, histogram_size);
final = DestroyMagickWand(final);

原始答案

很难说出你需要帮助的地方/内容。但要生成program.txt数据,您应该能够利用SPARES-COLOR:协议。

// ...
MagickSetImageAlphaChannel(wand, OffAlphaChannel);
MagickCompositeImage(wand, wand0, CopyAlphaCompositeOp, MagickFalse, 0, 0);

wand0 = DestroyMagickWand(wand0);

// Set image format to sparse protocol
MagickSetImageFormat(wand, "SPARSE-COLOR");
// Extract format data to buffer.
size_t blob_length = 0;
unsigned char * blob = MagickGetImageBlob(wand, &blob_length);
// Write buffer to file
FILE * fptr;
fptr = fopen("program.txt", "w");
fwrite(blob, sizeof(unsigned char), blob_length, fptr);
fclose(fptr);
free(blob);

wand = DestroyMagickWand(wand);
MagickWandTerminus();

甚至更简单

// ...
MagickSetImageAlphaChannel(wand, OffAlphaChannel);
MagickCompositeImage(wand, wand0, CopyAlphaCompositeOp, MagickFalse, 0, 0);

wand0 = DestroyMagickWand(wand0);

// Write sparse program
MagickWriteImage(wand, "SPARSE-COLOR:program.txt");

wand = DestroyMagickWand(wand);
MagickWandTerminus();