如何让颜色参数传递给稀疏颜色?

How to get color arguments to pass for sparse-color?

我一直在努力获得最高饱和度和最鲜艳的色彩。 为此,我有以下命令和 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;
}

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

Text file output from C

Text file output from CLI

删除 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);

原答案

很难说 where/what 您需要帮助。但是要生成 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();