将任意字节转换为任何无损的通用图像格式

时间:2017-02-22 01:20:47

标签: image encoding imagemagick

如何将具有最多320k字节的文件转换为具有1,2或3字节(任何可能)颜色的图像?

我想通过将320k的数据中的100%表示为打印在我的项目卡上的位图图像来展示我的1980年代应用程序的小小。

知道数据看起来不像噪音,但是没关系。我只想说:“就是这样 - 那些像素唯一地代表了这个应用程序中的每一个字节!”

如果有一个“2D条形码”应用程序可以做到这一点很酷,但经过一个小时的搜索后,我找不到一个有能力并且已经实现的应用程序(很多论文。)

1 个答案:

答案 0 :(得分:2)

  

可以强迫imageMagick这样做吗?

绝对!

让我们开始生成一个大小为320k的程序文件。

dd if=/dev/urandom of=myProgram.blob bs=1000 count=320

YMMV

灰色方法。单通道8位图像。

cat myProgram.blob | \
   convert -size 500x640 -depth 8 -format GRAY GRAY:-  gray_output.png 

gray_output.png

颜色方法。三通道8位图像。

cat  myProgram.blob | \
   convert -size 500x213 -depth 8 -format RGB RGB:- rgb_output.png

rgb_output.png

你需要做一些数学运算才能确定图像尺寸,但这很容易。

total_bytes = [number of channels] * width * height
  

我知道数据看起来不像噪音,但没关系。我只想说:

     
    

“就是这样 - 这些像素唯一地代表了这个应用程序中的每个字节!”

  

大约一年前,我遇到了同样的问题。我需要一个快速的视觉校验和“一目了然”,以确定数据blob是否不同。

所以,我创建了vizsum。绝不是无损的,或数学上安全的,但在眼睛上更漂亮。

 cat myProgram.blob | vizsum -sha1 -bilinear visual_checksum.png

visual_checksum.png

更新只是为了好玩。

这是使用MagickWand API

的快速C程序
// program2img.c
#include <stdio.h>
#include <math.h>
#include <wand/MagickWand.h> // Or <MagickWand/MagickWand.h> if using IM 7.x.x

int main(int argc, const char * argv[]) {

    FILE
        * fd;

    const char
        * input,
        * output;

    unsigned char
        * buffer;

    long
        program_size,
        program_area,
        program_width,
        program_width_data,
        program_height,
        col,
        row;

    MagickBooleanType ok;

    // Collect input / output
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <input> <output>\n", argv[0]);
        return 1;
    }
    input = argv[1];
    output = argv[2];

    // Open input for reading
    fd = fopen(argv[1], "rb");
    if (fd == NULL) {
        fprintf(stderr, "Unable to open `%s'\n", argv[1]);
        return 1;
    }

    // Get size of input
    fseek(fd, 0L, SEEK_END);
    program_size = ftell(fd);
    fseek(fd, 0L, SEEK_SET);

    // Roughly calculate size of output image.
    program_area = program_size / 3;
    program_width = sqrtl(program_area);
    if (program_width < 1) {
        fprintf(stderr, "Unable to generate image width\n");
        return 1;
    }
    program_width_data = program_width * 3;
    program_height = program_area / program_width + 1;
    if (program_height < 1) {
        fprintf(stderr, "Unable to generate image width\n");
        return 1;
    }

    // Boot ImageMagick
    MagickWandGenesis();

    PixelWand * color;
    MagickWand * wand;

    color = NewPixelWand();
    wand = NewMagickWand();

    PixelSetColor(color, "BLACK");
    MagickNewImage(wand, program_width, program_height, color);
    color = DestroyPixelWand(color);

    buffer = malloc(program_width_data);

    // Iterate over input and build image line-by-line
    for (row = 0; row < program_height; ++row) {
        col = fread(buffer, 1, program_width_data, fd);
        // Add padding (might need to double check this logic)
        while (col < program_width_data) {
            buffer[col++] = '\0';
        }
        MagickImportImagePixels(wand,
                                0, row,
                                program_width, 1,
                                "RGB", CharPixel, buffer);
    }
    fclose(fd);
    // Save image output.
    ok = MagickWriteImage(wand, output);
    if (ok == MagickFalse) {
        fprintf(stderr, "Unable to save output `%s'\n", output);
    }
    wand = DestroyMagickWand(wand);

    MagickWandTerminus();
    return 0;
}

可以用

编译
clang `MagickWand-config --cflags --libs` program2img.c -o program2img

并使用

./program2img mySmallProgram output.png

output.png

相关问题