[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
win32 imread and imwrite
From: |
Rahman Mohamud Faisal MOORABY |
Subject: |
win32 imread and imwrite |
Date: |
Thu, 22 Apr 2004 17:32:30 -0500 |
Hi listers
I managed to make the imread and imwrite M files work on win32 platforms.
They should still work on unix platforms as well. Would be great to get
your feedback.
You will need to set isunix to false in isunix.m
The problems where :
octave uses the unix file tree while the path to image magick must be in
win32 format.
------------------------------------------------------------------------------------------------------------------------------
#IMREAD: read images into octave from various file formats
#
# Note: this requires the ImageMagick "convert" utility
# get this from www.imagemagick.org if required
# additional documentation of options is available from the
# convert man page
#
# BASIC USAGE:
# img = imread( fname )
# - img is a greyscale (0-255) of image in fname
# [im,map]=imread( fname )
# - map is a matrix of [r,g,b], 0-1 triples
# - img is a matrix on indeces into map
# [r,g,b]= imread( fname )
# - r,g,b are red,green,blue (0-255) compondents
#
# Formats for image fname
# 1. simple guess from extention ie "fig.jpg", "blah.gif"
# 2. specify explicitly "jpg:fig.jpg", "gif:blah.gif"
# 3. specify subimage for multi-image format "tiff:file.tif[3]"
# 4. raw images (row major format) specify geometry
# "raw:img[256x180]"
#
# IMREAD OPTIONS:
# imread will support most of the options for convert.1
#
# img = imread( fname , options)
# [r,g,b]= imread( fname , options)
#
# where options is a string matrix (or list) of options
#
# example: options= ["-rotate 25";
# "-crop 200x200+150+150";
# "-sample 200%" ];
# will rotate, crop, and then expand the image.
# note that the order of operations is important
#
# The following options are supported
# -antialias remove pixel-aliasing
# -blur geometry blur the image
# -border geometry surround image with a border of color
# -bordercolor color border color
# -colors value maximum number of colors in the image
# -colorspace type alternate image colorspace
# -contrast enhance or reduce the image contrast
# -crop geometry preferred size and location of the cropped image
# -despeckle reduce the speckles within an image
# -dither apply Floyd/Steinberg error diffusion to image
# -draw string annotate the image with a graphic primitive
# -edge radius apply a filter to detect edges in the image
# -emboss radius emboss an image
# -enhance apply a digital filter to enhance a noisy image
# -equalize perform histogram equalization to an image
# -filter type use this filter when resizing an image
# -flip flip image in the vertical direction
# -flop flop image in the horizontal direction
# -font name font for rendering text
# -frame geometry surround image with an ornamental border
# -fuzz distance colors within this distance are considered equal
# -gamma value level of gamma correction
# -geometry geometry perferred size or location of the image
# -gaussian geometry gaussian blur an image
# -gravity type vertical and horizontal text placement
# -implode amount implode image pixels about the center
# -intent type Absolute, Perceptual, Relative, or Saturation
# -interlace type None, Line, Plane, or Partition
# -level value adjust the level of image contrast
# -map filename transform image colors to match this set of colors
# -median radius apply a median filter to the image
# -modulate value vary the brightness, saturation, and hue
# -monochrome transform image to black and white
# -mosaic create an mosaic from an image sequence
# -negate replace every pixel with its complementary color
# -noise radius add or reduce noise in an image
# -normalize transform image to span the full range of colors
# -paint radius simulate an oil painting
# -raise value lighten/darken image edges to create a 3-D effect
# -region geometry apply options to a portion of the image
# -roll geometry roll an image vertically or horizontally
# -rotate degrees apply Paeth rotation to the image
# -sample geometry scale image with pixel sampling
# -scale geometry resize image
# -scene value image scene number
# -segment values segment an image
# -seed value pseudo-random number generator seed value
# -shade degrees shade the image using a distant light source
# -sharpen geometry sharpen the image
# -shave geometry shave pixels from the image edges
# -shear geometry slide one edge of the image along the X or Y axis
# -size geometry width and height of image
# -solarize threshold negate all pixels above the threshold level
# -spread amount displace image pixels by a random amount
# -swirl degrees swirl image pixels about the center
# -texture filename name of texture to tile onto the image background
# -threshold value threshold the image
# -transparent color make this color transparent within the image
# -treedepth value depth of the color tree
# -type type image type
# -unsharp geometry sharpen the image
# -wave geometry alter an image along a sine wave
# Author: Andy Adler
function [out1,out2,out3]= imread(filename, options );
try save_empty_list_elements_ok= empty_list_elements_ok;
catch save_empty_list_elements_ok= 0;
end
try save_warn_empty_list_elements= warn_empty_list_elements;
catch save_warn_empty_list_elements= 0;
end
unwind_protect
empty_list_elements_ok= 1;
warn_empty_list_elements= 0;
if (nargin == 0)
usage (["img = imread (filename,options)\n", ...
"[r,g,b]= imread (filename,options)\n", ...
"[img,map]=imread (filename,options)" ]);
elseif (! isstr (filename))
error ("imread: expecting filename as a string");
endif
if any(filename==':') || any(filename=='[')
# we've using special imagemagick characters, so we don't
# do any octave path processing
fname= filename;
else
fname= file_in_path(IMAGEPATH,filename);
if isempty(fname)
error(['imread: file ' filename ' not found']);
end
end
# Put together the options string
# TODO: add some error checking here
if nargin==1
option_str="";
else
option_str="";
if ( is_list( options ) )
for i= 1:length(options)
option_str=[option_str," ", nth(options,i) ];
end
elseif ( isstr( options ) )
for i= 1:size(options,1)
option_str=[option_str," ", options(i,:) ];
end
else
error ("imread: expecting options as a string");
end
end
#
# decode the nargout to output what the user wants
#
if nargout==3;
wantgreyscale= 0;
wantmap= 0;
outputtype="ppm";
elseif nargout==2;
wantgreyscale= 0; wantmap= 1;
outputtype="ppm";
else
wantgreyscale= 1; wantmap= 0;
outputtype="pgm";
end
# pname= sprintf("convert %s '%s' %s:- 2>/dev/null",
# pname= sprintf("convert %s '%s' %s:- ",
# option_str, fname, outputtype);
# fid= popen(pname ,'r');
# disp(pname); disp(fid);
# create temporary file name
tnam= tmpnam();
if (isunix);
printf("You are running the UN*X version of ImRead\n");
cmd= sprintf("convert %s '%s' %s:%s 2>/dev/null ",
option_str, fname, outputtype, tnam);
else
printf("You are running the WiNdOWz version of ImRead\n");
# convert input file path into windowz format
fname=sprintf("cygpath -w %s", fname);
fname=system(fname);
# change the '\' strokes to '/' in the path name to prevent string
conflicts
for i=1:length(fname)
if fname(i)=='\\';
fname(i)='/';
end
end
# this routine because a newline character is added into fname (maybe bug
in the "file_in_path" function <see line 123>. This has to be removed.
if double(fname(length(fname))) >122 || double(fname(length(fname)))
<65;
fname=fname(1:length(fname)-1);
end
# create the command string
cmd= sprintf("convert %s ""%s""
%s:""%s""",option_str,fname,outputtype,tnam);
# command string convert the input file name path back to UN*X form
fname=sprintf("cygpath -u ""%s""", fname);
# Again convert the '\' strokes to '/' to prevent conflicts
for i=1:length(tnam)
if tnam(i)=='\\';
tnam(i)='/';
end
end
# do same for the temp file name created
for i=1:length(tnam)
if tnam(i)=='\\';
tnam(i)='/';
end
end
# execute command string to change filename to UN*X format
fname=system(fname);
# create command string to convert temporary file name path to unix
format
if tnam(2)==':';
tnam(2)=tnam(1);
tnam(1)='/';
tnam=sprintf("/cygdrive%s",tnam);
end
end
system(cmd);
fid= fopen(tnam,"rb");
#
# can we open the pipe?
# if not 1) The file format is wrong and the conver program has bailed out
# 2) The apropriate converter program hasn't been installed
#
if fid<0;
unlink(tnam);
error(['could not read file: ' tnam]);
end
# get file type
line= fgetl( fid );
if strcmp(line, 'P1'); bpp=1; spp=1; bindata=0;
elseif strcmp(line, 'P4'); bpp=1; spp=1; bindata=1;
elseif strcmp(line, 'P2'); bpp=8; spp=1; bindata=0;
elseif strcmp(line, 'P5'); bpp=8; spp=1; bindata=1;
elseif strcmp(line, 'P3'); bpp=8; spp=3; bindata=0;
elseif strcmp(line, 'P6'); bpp=8; spp=3; bindata=1;
else
# pclose(fid);
fclose(fid); unlink(tnam);
error(['Image format error for ',fname,':line=', setstr(line)]);
end
# ignore comments
line= fgetl( fid );
while length(line)==0 || line(1)=='#'
line= fgetl( fid );
end
# get width, height
[wid, hig]= sscanf( line, '%d %d', 'C' );
# get max component value
if bpp==8
max_component= sscanf( fgetl(fid), '%d' );
if (max_component > 255)
# The PGM standard supports only values below 65536
bpp = 16;
endif
end
if bindata
if(bpp == 16)
# PGM format has MSB first, i.e. big endian
data = fread(fid, "uint16", 0, "ieee-be");
else
data = fread(fid);
endif
numdata= size(data,1);
if bpp==1
data= rem( floor( (data*ones(1,8)) ./ ...
(ones(length(data),1)*[128 64 32 16 8 4 2 1]) ), 2)';
end
else
numdata= wid*hig*spp;
data= zeros( numdata,1 );
dptr= 1;
line= fgetl( fid );
while !feof( fid)
rdata= sscanf( line ,' %d');
nptr= dptr + size(rdata,1);
data( dptr:nptr-1 ) = rdata;
dptr= nptr;
line= fgetl( fid );
end # feof
end #if bindata
# pclose(fid);
fclose(fid); unlink(tnam);
if spp==1
greyimg= reshape( data(:), wid, hig )';
elseif spp==3
redimg= reshape( data(1:spp:numdata), wid, hig )';
grnimg= reshape( data(2:spp:numdata), wid, hig )';
bluimg= reshape( data(3:spp:numdata), wid, hig )';
else
error(sprintf("imread: don't know how to handle pnm with
spp=%d",spp));
end
# This section outputs the image in the desired output format
# if the user requested the colour map, the we regenerate it from
# the image.
#
# Of course, 1) This may result in huge colourmaps
# 2) The colourmap will not be in the same order as
# in the original file
if wantgreyscale
if exist('greyimg')
out1= greyimg;
elseif exist('idximg')
greymap= mean(map')';
out1= reshape( greymap( idximg ) , size(idximg,1), size(idximg,2) );
else
out1= ( redimg+grnimg+bluimg ) / 3 ;
end
elseif wantmap
if exist('idximg')
out1= idximg;
out2= map;
elseif exist('greyimg')
[simg, sidx] = sort( greyimg(:) );
[jnkval, sidx] = sort( sidx );
dimg= [1; diff(simg)>0 ];
cimg= cumsum( dimg );
out1= reshape( cimg( sidx ) , hig, wid);
out2= ( simg(find( dimg ))*[1,1,1] - 1)/256;
else
#
# Generate a colourmap for RGB images by packing RGB into
# an integer and assigning the unique values to a colormap.
#
c_range= 256; # use 65536 for 48 bit color
[simg, sidx] = sort( round(redimg(:)) + ...
c_range *round(grnimg(:)) + ...
c_range^2 *round(bluimg(:)) );
[jnkval, sidx] = sort( sidx );
dimg= [1; diff(simg)>0 ];
cimg= cumsum( dimg );
out1= reshape( cimg( sidx ) , hig, wid );
tmpv= simg(find( dimg ));
out2= [ rem(tmpv,c_range), ...
rem(floor(tmpv/c_range), c_range), ...
floor(tmpv/c_range^2) ]/c_range;
end
else
if exist('greyimg')
out1= greyimg;
out2= greyimg;
out3= greyimg;
else
out1= redimg;
out2= grnimg;
out3= bluimg;
end
end
unwind_protect_cleanup
empty_list_elements_ok= save_empty_list_elements_ok;
warn_empty_list_elements= save_warn_empty_list_elements;
end_unwind_protect
#
# $Log: imread.m,v $
# Revision 1.10 2004/04/15 11:24:10 Faisal Mooraby
# Support for Win32 platforms
#
# $Log: imread.m,v $
# Revision 1.9 2004/02/18 14:54:10 pkienzle
# Colour values from ppm are 0-255 not 1-256
#
# Revision 1.8 2003/11/14 16:55:10 tpikonen
# Fix endianess bug in 16-bit reads.
#
# Revision 1.6 2003/09/12 14:22:42 adb014
# Changes to allow use with latest CVS of octave (do_fortran_indexing, etc)
#
# Revision 1.5 2003/07/25 19:11:41 pkienzle
# Make sure all files names referenced in system calls are wrapped in quotes
# to protect against spaces in the path.
#
# Revision 1.4 2002/11/27 08:40:11 pkienzle
# author/license updates
#
# Revision 1.3 2002/03/19 18:14:13 aadler
# unfortunately using popen seems to create problems, mostly
# on win32, but also on linux, so we need to move to a tmpfile approach
#
# Revision 1.2 2002/03/17 05:26:14 aadler
# now accept filenames with spaces
#
# Revision 1.1 2002/03/11 01:56:47 aadler
# general image read/write functionality using imagemagick utilities
#
#
-------------------------------------------------------------------------------------------------------------------------------------------
#IMWRITE: write image from octave to various file formats
#
# Note: this requires the ImageMagick "convert" utility.
# get this from www.imagemagick.org if required
# additional documentation of options is available from the
# convert man page
#
# BASIC USAGE:
# imwrite( fname, img )
# - img is a greyscale (0-255) of image in fname
# imwrite( fname, img, map )
# - map is a matrix of [r,g,b], 0-1 triples
# - img is a matrix on indeces into map
# imwrite( fname, r,g,b );
# - r,g,b are red,green,blue (0-255) compondents
#
# Formats for image fname
# 1. simple guess from extention ie "fig.jpg", "blah.gif"
# 2. specify explicitly "jpg:fig.jpg", "gif:blah.gif"
# 3. specify subimage for multi-image format "tiff:file.tif[3]"
# 4. raw images (row major format) specify geometry
# "raw:img[256x180]"
#
# IMREAD OPTIONS:
# imread will support most of the options for convert.1
#
# imwrite( fname, img, options )
# imwrite( fname, img, map, options )
# imwrite( fname, r,g,b, options );
#
# where options is a string matrix (or list) of options
#
# example: options= ["-rotate 25";
# "-crop 200x200+150+150";
# "-sample 200%" ];
# will rotate, crop, and then expand the image.
# note that the order of operations is important
#
# The following options are supported
# -antialias remove pixel-aliasing
# -background color background color
# -blur geometry blur the image
# -border geometry surround image with a border of color
# -bordercolor color border color
# -box color color for annotation bounding box
# -charcoal radius simulate a charcoal drawing
# -colorize value colorize the image with the fill color
# -colors value preferred number of colors in the image
# -colorspace type alternate image colorspace
# -comment string annotate image with comment
# -compress type type of image compression
# -contrast enhance or reduce the image contrast
# -crop geometry preferred size and location of the cropped image
# -density geometry vertical and horizontal density of the image
# -depth value depth of the image
# -despeckle reduce the speckles within an image
# -dispose method GIF disposal method
# -dither apply Floyd/Steinberg error diffusion to image
# -draw string annotate the image with a graphic primitive
# -edge radius apply a filter to detect edges in the image
# -emboss radius emboss an image
# -enhance apply a digital filter to enhance a noisy image
# -equalize perform histogram equalization to an image
# -fill color color to use when filling a graphic primitive
# -filter type use this filter when resizing an image
# -flip flip image in the vertical direction
# -flop flop image in the horizontal direction
# -font name font for rendering text
# -frame geometry surround image with an ornamental border
# -fuzz distance colors within this distance are considered equal
# -gamma value level of gamma correction
# -geometry geometry perferred size or location of the image
# -gaussian geometry gaussian blur an image
# -gravity type vertical and horizontal text placement
# -implode amount implode image pixels about the center
# -intent type Absolute, Perceptual, Relative, or Saturation
# -interlace type None, Line, Plane, or Partition
# -label name assign a label to an image
# -level value adjust the level of image contrast
# -list type Color, Delegate, Format, Magic, Module, or Type
# -map filename transform image colors to match this set of colors
# -matte store matte channel if the image has one
# -median radius apply a median filter to the image
# -modulate value vary the brightness, saturation, and hue
# -monochrome transform image to black and white
# -morph value morph an image sequence
# -negate replace every pixel with its complementary color
# -noise radius add or reduce noise in an image
# -normalize transform image to span the full range of colors
# -opaque color change this color to the fill color
# -page geometry size and location of an image canvas
# -paint radius simulate an oil painting
# -profile filename add ICM or IPTC information profile to image
# -quality value JPEG/MIFF/PNG compression level
# -raise value lighten/darken image edges to create a 3-D effect
# -region geometry apply options to a portion of the image
# -roll geometry roll an image vertically or horizontally
# -rotate degrees apply Paeth rotation to the image
# -sample geometry scale image with pixel sampling
# -scale geometry resize image
# -segment values segment an image
# -seed value pseudo-random number generator seed value
# -shade degrees shade the image using a distant light source
# -sharpen geometry sharpen the image
# -shave geometry shave pixels from the image edges
# -shear geometry slide one edge of the image along the X or Y axis
# -size geometry width and height of image
# -solarize threshold negate all pixels above the threshold level
# -spread amount displace image pixels by a random amount
# -stroke color color to use when stoking a graphic primitive
# -strokewidth value width of stroke
# -swirl degrees swirl image pixels about the center
# -texture filename name of texture to tile onto the image background
# -threshold value threshold the image
# -tile filename tile image when filling a graphic primitive
# -transparent color make this color transparent within the image
# -treedepth value depth of the color tree
# -type type image type
# -units type PixelsPerInch, PixelsPerCentimeter, or Undefined
# -unsharp geometry sharpen the image
# Author: Andy Adler
function imwrite(fname, p2, p3 ,p4 ,p5 );
try save_empty_list_elements_ok= empty_list_elements_ok;
catch save_empty_list_elements_ok= 0;
end
try save_warn_empty_list_elements= warn_empty_list_elements;
catch save_warn_empty_list_elements= 0;
end
unwind_protect
empty_list_elements_ok= 1;
warn_empty_list_elements= 0;
if ( nargin <= 1 ) || ...
( ! isstr (fname)) || ...
( nargin == 2 && isstr(p2) )
usage([ ...
"imwrite( fname, img )\n", ...
"imwrite( fname, img, map )\n", ...
"imwrite( fname, r,g,b );\n", ...
"imwrite( fname, img, options )\n", ...
"imwrite( fname, img, map, options )\n", ...
"imwrite( fname, r,g,b, options );\n"]);
endif
# Put together the options string
# TODO: add some error checking to options
option_str="";
n_mat= nargin-1;
options= eval(sprintf("p%d",nargin));
# process options strings if given
if isstr(options)
n_mat--;
for i= 1:size(options,1)
option_str=[option_str," ", options(i,:) ];
end
elseif is_list( options )
n_mat--;
for i= 1:length(options)
option_str=[option_str," ", nth(options,i) ];
end
end
[hig,wid] = size(p2);
if n_mat==1
data= p2';
outputtype="pgm";
pnm_sig="P5";
elseif n_mat==2
img= p2';
data= [ 255*reshape(p3(img,1),1, hig*wid);
255*reshape(p3(img,2),1, hig*wid);
255*reshape(p3(img,3),1, hig*wid) ];
outputtype="ppm";
pnm_sig="P6";
elseif n_mat==3
data= [ reshape(p2',1, hig*wid);
reshape(p3',1, hig*wid);
reshape(p4',1, hig*wid) ];
outputtype="ppm";
pnm_sig="P6";
else
error("imwrite: too many data matrices specified");
end
# pname= sprintf("convert %s %s:- '%s' 2>/dev/null",
# option_str, outputtype, fname);
# fid= popen(pname ,'w');
tnam= tmpnam();
# create temporary file name
tnam= tmpnam();
if (isunix);
printf("You are running the UN*X version of ImWrite\n");
cmd= sprintf("convert %s '%s:%s' '%s' 2>/dev/null",
option_str, outputtype, tnam, fname);
else
printf("You are running the WiNdOWz version of ImWrite\n");
# convert input file path into windowz format
fname=sprintf("cygpath -w %s", fname);
fname=system(fname);
# change the '\' strokes to '/' in the path name to prevent string
conflicts
for i=1:length(fname)
if fname(i)=='\\';
fname(i)='/';
end
end
# this routine because a newline character is added into fname (maybe
bug in the "file_in_path" function <see line 123>. This has to be removed.
if double(fname(length(fname))) >122 || double(fname(length(fname)))
<65;
fname=fname(1:length(fname)-1);
end
# create the command string
cmd= sprintf("convert %s ""%s:%s""
""%s""",option_str,outputtype,tnam, fname);
# command string convert the input file name path back to UN*X
form
fname=sprintf("cygpath -u ""%s""", fname);
# Again convert the '\' strokes to '/' to prevent conflicts
for i=1:length(tnam)
if tnam(i)=='\\';
tnam(i)='/';
end
end
# do same for the temp file name created
for i=1:length(tnam)
if tnam(i)=='\\';
tnam(i)='/';
end
end
# execute command string to change filename to UN*X format
fname=system(fname);
# create command string to convert temporary file name path to unix
format
if tnam(2)==':';
tnam(2)=tnam(1);
tnam(1)='/';
tnam=sprintf("/cygdrive%s",tnam);
end
end
fid= fopen(tnam, "wb");
# disp(pname); disp(fid);
if fid<0;
error(['could not create file: ',tnam]);
end
fprintf(fid,"%s\n%d %d\n255\n",pnm_sig,wid,hig);
write_count= fwrite(fid,data(:));
if write_count != prod(size(data))
fclose(fid); unlink(tnam);
error(['Unable to write image: ', fname ]);
end
fclose(fid);
[jnk,retcode] = system(cmd);
if retcode !=0
error('could not call imagemagick convert');
end
unlink( tnam );
unwind_protect_cleanup
empty_list_elements_ok= save_empty_list_elements_ok;
warn_empty_list_elements= save_warn_empty_list_elements;
end_unwind_protect
#
# $Log: imwrite.m,v $
# Revision 1.6 2003/09/12 14:22:42 adb014
# Changes to allow use with latest CVS of octave (do_fortran_indexing, etc)
#
# Revision 1.5 2003/07/25 19:11:41 pkienzle
# Make sure all files names referenced in system calls are wrapped in quotes
# to protect against spaces in the path.
#
# Revision 1.4 2002/11/27 08:40:11 pkienzle
# author/license updates
#
# Revision 1.3 2002/03/19 18:14:13 aadler
# unfortunately using popen seems to create problems, mostly
# on win32, but also on linux, so we need to move to a tmpfile approach
#
# Revision 1.2 2002/03/17 05:26:14 aadler
# now accept filenames with spaces
#
# Revision 1.1 2002/03/11 01:56:47 aadler
# general image read/write functionality using imagemagick utilities
#
#
-------------------------------------------------------------------------------------------------------------------------------------------
Faisal ...
_________________________________________________________________
Sign-up for a FREE BT Broadband connection today!
http://www.msn.co.uk/specials/btbroadband
-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.
Octave's home on the web: http://www.octave.org
How to fund new projects: http://www.octave.org/funding.html
Subscription information: http://www.octave.org/archive.html
-------------------------------------------------------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- win32 imread and imwrite,
Rahman Mohamud Faisal MOORABY <=