对于3D矩阵,我通常会将它们转换为VRML3D格式,并使用ParallelGraphics/Cortona3D进行查看。
否则,您需要对矩阵进行某种投影或“切片”,以便查看整个矩阵。
这是一个用于将3D矩阵转储到PNG文件的C语言实现。编译方式为:
gcc -W -Wall -o bin2png bin2png.c -lpng
代码:
#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;
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)) ){
png_destroy_write_struct(&png_ptr, &info_ptr);
return -2;
}
if (NULL == (row = malloc(WW*W + 7)))
{
return -3;
}
#define SETPAL(i,r,g,b,a) \
palette[i].red = r; palette[i].green = g; palette[i].blue = b; transparencies[i] = 255-a;
#define INDEX_IF_ZERO 0
#define INDEX_IF_NONZERO 3
#define INDEX_IF_BLANK 15
SETPAL(0, 0, 0, 0, 0);
SETPAL(1, 255, 255, 255, 0);
SETPAL(2, 192, 192, 192, 0);
SETPAL(3, 255, 0, 0, 0);
SETPAL(4, 0, 255, 0, 0);
SETPAL(5, 0, 0, 255, 0);
SETPAL(6, 255, 0, 0, 128);
SETPAL(7, 0, 255, 0, 128);
SETPAL(8, 0, 0, 255, 128);
SETPAL(9, 255, 0, 0, 0);
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);
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 );
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;
}