Convert binary file to image

匆匆过客 提交于 2021-02-08 13:35:18

问题


I need to find a fast way to convert a binary file to an image. The binary file consist of a NNN matrix and I want to associate 0 to a color and 1 to a different color. I need to perform this operation to more then 1000 binary files. If possible I'd like to avoid using MatLab, is there any tool/software (for unix) that would help me?

EDIT:

This is exactly what I was looking for! On the bottom of the page it says: "TIP: To process many files, use a shell script to pass this URL and your desired parameters to wget and then direct the output to file" Yet I can't do this. I tried with:

 wget --post-data="blocksize=10&width=10&offset=0&markval=-1&autoscale=0"  \
      --post-file="userfile=/path.../filename" http://www.ryanwestafer.com/stuff/bin2img.php \
      > output

but all I get is the original page downloaded in my local folder!


回答1:


If you have python with the PIL (Image) library installed:

import Image
def colormap(s):
    s_out = []
    for ch in s:   # assume always '\x00' or '\x01'
        if s == '\x00':
            s_out.append('\x00')  # black
        else:
            s_out.append('\xFF')  # white
    return ''.join(s_out)

N= 50   # for instance
fin = open('myfile.bin','rb')
data = fin.read(N*N)    # read NxN bytes
data = colormap(data)

# convert string to grayscale image

img = Image.fromstring('L', (N,N), data )
# save to file
img.save('thisfile.png')

data = fin.read(N*N)   # next NxN bytes
data = colormap(data)

img = Image.fromstring('L', (N,N), data )
img.save('thisfile2.png')

This can be easily modified to loop and sequence filenames, etc as needed




回答2:


For 3D matrixes, I would usually convert them to VRML3D and look at them using ParallelGraphics/Cortona3D.

Otherwise, you need some sort of projection or "slicing" of the matrix in order to see all of the matrix.

This is a C implementation to dump a 3D matrix to a PNG file. Compile with

gcc -W -Wall -o bin2png bin2png.c -lpng

Code:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <png.h>

static png_structp png_ptr;
static png_infop info_ptr;

/**
                      |<--- W ---->|

                      +------------+       -
                      | 18  19   20|       |
                  +-------------+  |       |
                  | 9   10   11 |  |       |
              +-------------+   |23|       +--> H
              | 0    1    2 |   |  |       |
              |             |14 |  |       |
              |             |   |26|       |
              | 3    4    5 |   |--+   +   -
              |             |17 |     /
              |             |---+    +--> D
              | 6    7    8 |       /
              +-------------+      +

        @param matrix   a 3D matrix. Element [i,j,k] is A[H*(D*k + j) + i]
        @param W        width
        @param H        height
        @param D        depth
        @param WW       width in W-sized chunks of target image
        @param HH       height in H-sized chunks of target image
        @param filename output filename in PNG format

        Output image:


        |<----- WW = 2 --->|
        +------------------+ -
        |  0  1  2  9 10 11| |
        |  3  4  5 12 13 14| |
        |  6  7  8 15 16 17| HH = 2
        | 18 19 20         | |
        | 21 22 23  blank  | |
        | 24 25 26         | |
        +------------------+ -

        NOTE: W*WW and H*HH may not exceed 32760.

        Return:
                0       success
                -1      cannot create PNG structure (write)
                -2      cannot create PNG structure (info)
                -3      out of memory
                -4      cannot create output file

*/

int matrix3D_to_png(uint8_t *matrix, size_t W, size_t H, size_t D, size_t WW, size_t HH, char *filename)
{
        FILE            *fp;
        png_color       palette[16];
        png_byte        transparencies[16];
        uint32_t        y;
        size_t          x;
        uint8_t         *row;

        if( !(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) )
                return -1;

        if( !(info_ptr = png_create_info_struct(png_ptr)) || setjmp(png_jmpbuf(png_ptr)) ){
                /* If we get here, libpng had a problem writing */
                png_destroy_write_struct(&png_ptr, &info_ptr);
                return -2;
        }

        if (NULL == (row        = malloc(WW*W + 7)))
        {
                return -3;
        }

        /* Create 16-color palette for representation */
        #define SETPAL(i,r,g,b,a)       \
        palette[i].red  = r; palette[i].green   = g; palette[i].blue    = b; transparencies[i] = 255-a;

        // We will draw the matrix in red if points are nonzero, black if zero; outside the matrix
        // we use transparent white.
        #define         INDEX_IF_ZERO           0
        #define         INDEX_IF_NONZERO        3
        #define         INDEX_IF_BLANK          15

        SETPAL(0,       0, 0, 0, 0);            // Black
        SETPAL(1,       255, 255, 255, 0);      // Opaque white
        SETPAL(2,       192, 192, 192, 0);      // Light gray

        SETPAL(3,       255,    0,      0, 0);  // Red
        SETPAL(4,       0,      255,    0, 0);  // Green
        SETPAL(5,       0,      0,      255, 0);// Blue

        SETPAL(6,       255,    0,      0,      128);   // Halftransparent red
        SETPAL(7,       0,      255,    0,      128);   // green
        SETPAL(8,       0,      0,      255,    128);   // blue

        SETPAL(9,       255, 0, 0, 0);          // red again :-)
        SETPAL(10,      0, 255, 0, 0);
        SETPAL(11,      0, 0, 255, 0);
        SETPAL(12,      255, 0, 0, 0);
        SETPAL(13,      0, 255, 0, 0);
        SETPAL(14,      0, 0, 255, 0);

        SETPAL(15,      255, 255, 255, 255);    // Transparent white
        /* End palette */

        /* Create filename */
        if (NULL == (fp = fopen(filename, "w")))
        {
                fprintf(stderr, "cannot open output '%s': %s\n", filename, strerror(errno));
                return -4;
        }
        png_init_io(png_ptr, fp);
        png_set_IHDR(png_ptr, info_ptr, W*WW, H*HH, 8, PNG_COLOR_TYPE_PALETTE,
                                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
        png_set_PLTE(png_ptr, info_ptr, palette, 16);
        png_set_tRNS(png_ptr, info_ptr, transparencies, 16, NULL);
        png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
        png_write_info(png_ptr, info_ptr);
        for (y = 0; y < H*HH; y++)
        {
                size_t  mx = y/H;
                mx      = (mx*H*WW + (y%H))*W;
                for (x = 0; x < WW; x++)
                {
                        if (mx+x*H >= H*D)
                                memset(row+x*W, INDEX_IF_BLANK, W);
                        else
                        {
                                size_t ii;
                                for (ii = 0; ii < W; ii++)
                                        row[x*W+ii] = (matrix[mx+x*W*H+ii]) ? INDEX_IF_NONZERO : INDEX_IF_ZERO;
                        }
                }
                png_write_row(png_ptr, row);
        }
        png_write_end(png_ptr, NULL /*info_ptr*/);
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);
        free(row);
        return 0;
}

int main(int argc, char **argv)
{
        FILE    *fp;
        uint8_t *matrix;
        size_t  W, H, D, WW, HH, i;
        if (8 != argc)
        {
                fprintf(stderr, "Syntax: %s input output.png width height depth TileX TileY\n", *argv);
                return EXIT_FAILURE;
        }
        W       = atol(argv[3]);
        H       = atol(argv[4]);
        D       = atol(argv[5]);
        WW      = atol(argv[6]);
        HH      = atol(argv[7]);

        if ((W * WW > 32767)||(H * HH) > 32767)
        {
                fprintf(stderr, "Output image would be too large\n");
                return EXIT_FAILURE;
        }
        if (WW*HH < D)
        {
                fprintf(stderr, "WARNING: matrix does not fit into output image\n");
        }
        if (WW*HH > D*2)
        {
                fprintf(stderr, "WARNING: output image is far larger than input matrix\n");
        }
        if (NULL == (fp = fopen(argv[1], "r")))
        {
                fprintf(stderr, "Input file not found\n");
                return EXIT_FAILURE;
        }
        if (NULL == (matrix = malloc(W*H*D)))
        {
                fprintf(stderr, "Out of memory: matrix too large\n");
                return EXIT_FAILURE;
        }
        for (i = 0; i < D; i++)
        {
                int ret;
                if ((int)H != (ret = fread(matrix + W*H*i, W, H, fp)))
                {
                        fprintf(stderr, "Read error at plane %d (reading %d rows of %d elements, expecting %d, got %d)\n",
                                (int)i, (int)W, (int)H, (int)H, ret);
                        fclose(fp);
                        return EXIT_FAILURE;
                }
        }
        if (matrix3D_to_png(matrix, W, H, D, WW, HH, argv[2]))
        {
                fprintf(stderr, "Error in creating output PNG '%s'\n", argv[2]);
                return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
}



回答3:


GNU Octave is a free Matlab-like program that a lot of people seem to like.

This site has a whole list of free alternatives: http://www.math.tu-berlin.de/~ehrhardt/matlab_alternatives.html



来源:https://stackoverflow.com/questions/14092289/convert-binary-file-to-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!