I finished a saver operation for floating point npy images. It may e.g. be used to debug floating point operations (e.g. gaussian-blur) with numerical python. The resulting image may be read into numpy as follows:
import numpy img = numpy.load('image.npy') It may also be viewed in my image viewer giv (though it currently does not support color npy images). Is it ok to commit it? Follows the code. Regards, Dov /* This file is an image processing operation for GEGL * * GEGL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * GEGL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with GEGL; if not, see <http://www.gnu.org/licenses/>. * * Copyright Dov Grobgeld 2013 <dov.grobgeld (a) gmail.com> * * This operation saves a buffer in the npy file format. It may be * read into python as follows: * * import numpy * img = numpy.load('image.npy') */ #include "config.h" #include <glib/gi18n-lib.h> #ifdef GEGL_CHANT_PROPERTIES gegl_chant_string (path, _("File"), "", _("Target path and filename, use '-' for stdout.")) #else #define GEGL_CHANT_TYPE_SINK #define GEGL_CHANT_C_FILE "npy-save.c" #include "gegl-chant.h" #include <stdio.h> static int npywrite(FILE *fp, guchar *data, int width, int height, int num_channels) { char header[100]; unsigned short header_len; // Write header and version number to file fwrite("\223NUMPY" "\001\000" , 1, 8, fp); if (num_channels == 3) sprintf(header, "{'descr': '<f4', 'fortran_order': False, 'shape': (%d, %d, 3), } \n", height, width); else sprintf(header, "{'descr': '<f4', 'fortran_order': False, 'shape': (%d, %d), } \n", height, width); header_len = strlen(header); fwrite(&header_len, 2, 1, fp); fwrite(header, header_len, 1, fp); fwrite(data, width*height*num_channels, sizeof(float), fp); return 0; } static gboolean process (GeglOperation *operation, GeglBuffer *input, const GeglRectangle *rect, gint level) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); FILE *fp; guchar *data; gsize bpc; gsize numsamples; gsize numchannels; gboolean ret = FALSE; const Babl *output_format; const Babl *input_format = gegl_buffer_get_format(input); // Get the current format and use it to decide whether to save // the output in color or gray level formats. bpc = sizeof(gfloat); if (babl_format_get_n_components(input_format) >= 3) { numchannels = 3; output_format = babl_format("RGB float"); } else { numchannels = 1; output_format = babl_format ("Y float"); } numsamples = rect->width * rect->height * numchannels; data = g_malloc (numsamples * bpc); gegl_buffer_get (input, rect, 1.0, output_format, data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); fp = (!strcmp (o->path, "-") ? stdout : fopen(o->path, "wb") ); npywrite(fp, data, rect->width, rect->height, numchannels); g_free (data); return ret; } static void gegl_chant_class_init (GeglChantClass *klass) { GeglOperationClass *operation_class; GeglOperationSinkClass *sink_class; operation_class = GEGL_OPERATION_CLASS (klass); sink_class = GEGL_OPERATION_SINK_CLASS (klass); sink_class->process = process; sink_class->needs_full = TRUE; gegl_operation_class_set_keys (operation_class, "name" , "gegl:npy-save", "categories" , "output", "description" , _("NPY image saver (Numerical python file saver.)"), NULL); gegl_extension_handler_register_saver (".npy", "gegl:npy-save"); } #endif
_______________________________________________ gegl-developer-list mailing list gegl-developer-list@gnome.org https://mail.gnome.org/mailman/listinfo/gegl-developer-list