问题
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