1\chapter{Python Bindings} 2\label{chap:pythonbindings} 3\indexapi{Python|()} 4 5\section{Overview} 6 7\OpenImageIO provides Python language bindings for much of its 8functionality. 9 10\smallskip 11 12You must ensure that the environment variable {\cf PYTHONPATH} includes 13the {\cf python} subdirectory of the \OpenImageIO installation. 14 15\smallskip 16 17A Python program must import the {\cf OpenImageIO} package: 18\begin{code} 19 import OpenImageIO 20\end{code} 21\noindent In most of our examples below, we assume that for the sake 22of brevity, we will alias the package name as follows: 23\begin{code} 24 import OpenImageIO as oiio 25 from OpenImageIO import ImageInput, ImageOutput 26 from OpenImageIO import ImageBuf, ImageSpec, ImageBufAlgo 27\end{code} 28 29\section{TypeDesc} 30\label{sec:pythontypedesc} 31 32The \TypeDesc class that describes data types of pixels and metadata, 33described in detail in Section~\ref{sec:TypeDesc}, is replicated for Python. 34 35\apiitem{BASETYPE} 36The {\cf BASETYPE} enum corresponds to the C++ {\cf TypeDesc::BASETYPE} and 37contains the following values: \\ 38{\cf UNKNOWN NONE UINT8 INT8 UINT16 INT16 UINT32 INT32 UINT64 INT64 \\ 39HALF FLOAT DOUBLE STRING PTR} \\ 40These names are also exported to the {\cf OpenImageIO} namespace. 41\apiend 42 43\apiitem{AGGREGATE} 44The {\cf AGGREGATE} enum corresponds to the C++ {\cf TypeDesc::AGGREGATE} and 45contains the following values: \\ 46{\cf SCALAR VEC2 VEC3 VEC4 MATRIX33 MATRIX44} \\ 47These names are also exported to the {\cf OpenImageIO} namespace. 48\apiend 49 50\apiitem{VECSEMANTICS} 51The {\cf VECSEMANTICS} enum corresponds to the C++ {\cf TypeDesc::VECSEMANTICS} and 52contains the following values: \\ 53{\cf NOSEMANTICS COLOR POINT VECTOR NORMAL TIMECODE KEYCODE RATIONAL} \\ 54These names are also exported to the {\cf OpenImageIO} namespace. 55\apiend 56 57\apiitem{TypeDesc.{\ce TypeDesc} (typename='unknown')} 58 59Construct a {\cf TypeDesc} object the easy way: from a string description. 60If the type name is omitted, it will default to {\cf UNKNOWN}. 61 62\noindent Examples: 63\begin{code} 64 import OpenImageIO as oiio 65 66 # make a default (UNKNOWN) TypeDesc 67 t = TypeDesc() 68 69 # make a TypeDesc describing an unsigned 8 bit int 70 t = TypeDesc("uint8") 71 72 # make a TypeDesc describing an array of 14 'float' values 73 t = TypeDesc("float[14]") 74 75 # make a TypeDesc describing 3-vector with point semantics 76 t = TypeDesc("point") 77\end{code} 78\apiend 79 80\apiitem{TypeDesc.{\ce TypeDesc} (basetype=oiio.UNKNOWN, aggregate=oiio.SCALAR, \\ 81\bigspc\spc\spc vecsemantics=NOSEMANTICS, arraylen=0)} 82 83Construct a {\cf TypeDesc} object the hard way: from individual enum tokens 84describing the base type, aggregate class, semantic hints, and array length. 85 86\noindent Examples: 87\begin{code} 88 import OpenImageIO as oiio 89 90 # make a default (UNKNOWN) TypeDesc 91 t = TypeDesc() 92 93 # make a TypeDesc describing an unsigned 8 bit int 94 t = TypeDesc(oiio.UINT8) 95 96 # make a TypeDesc describing an array of 14 'float' values 97 t = TypeDesc(oiio.FLOAT, oiio.SCALAR, oiio.NOSEMANTICS, 14) 98 99 # make a TypeDesc describing a float point 100 t = TypeDesc(oiio.FLOAT, oiio.VEC3, oiio.POINT) 101\end{code} 102\apiend 103 104\apiitem{TypeUnknown TypeString \\ 105TypeFloat TypeHalf \\ 106TypeInt TypeUInt TypeInt16 TypeUInt16 \\ 107TypeColor TypePoint TypeVector TypeNormal TypeFloat4 \\ 108TypeMatrix TypeMatrix33 \\ 109TypeTimeCode TypeKeyCode \\ 110TypeRational \\ 111} 112Pre-constructed \TypeDesc objects for some common types, available in the 113outer OpenImageIO scope. 114 115\noindent Example: 116\begin{code} 117 t = TypeFloat 118\end{code} 119\apiend 120 121\apiitem{string {\ce str} (TypeDesc)} 122Returns a string that describes the \TypeDesc. 123 124\noindent Example: 125\begin{code} 126 print str(TypeDesc(oiio.UINT16)) 127 128 > int16 129\end{code} 130\apiend 131 132\apiitem{TypeDesc.{\ce basetype} \\ 133TypeDesc.{\ce aggregate} \\ 134TypeDesc.{\ce vecsemantics} \\ 135TypeDesc.{\ce arraylen}} 136Access to the raw fields in the \TypeDesc. 137 138\noindent Example: 139\begin{code} 140 t = TypeDesc(...) 141 if t.basetype == oiio.FLOAT : 142 print "It's made of floats" 143\end{code} 144\apiend 145 146\apiitem{int TypeDesc.{\ce size} () \\ 147int TypeDesc.{\ce basesize} () \\ 148TypeDesc TypeDesc.{\ce elementtype} () \\ 149int TypeDesc.{\ce numelements} () \\ 150int TypeDesc.{\ce elementsize} ()} 151The {\cf size()} is the size in bytes, of the type described. The 152{\cf basesize()} is the size in bytes of the {\cf basetype}. 153 154The {\cf elementtype()} is the type of each array element, if it is an 155array, or just the full type if it is not an array. The {\cf elementsize()} 156is the size, in bytes, of the {\cf elementtype} (thus, returning the same 157value as {\cf size()} if the type is not an array). The {\cf numelements()} 158method returns {\cf arraylen} if it is an array, or {\cf 1} if it is not 159an array. 160 161\noindent Example: 162\begin{code} 163 t = TypeDesc("point[2]") 164 print "size =", t.size() 165 print "elementtype =", t.elementtype() 166 print "elementsize =", t.elementsize() 167 168 > size = 24 169 > elementtype = point 170 > elementsize = 12 171\end{code} 172\apiend 173 174\apiitem{bool typedesc {\ce ==} typedesc \\ 175bool typedesc {\ce !=} typedesc \\ 176bool TypeDesc.{\ce equivalent} (typedesc) \\} 177Test for equality or inequality. The {\cf equivalent()} method is more 178forgiving than {\cf ==}, in that it considers {\cf POINT}, {\cf VECTOR}, 179and {\cf NORMAL} vector semantics to not constitute a difference from one 180another. 181 182\noindent Example: 183\begin{code} 184 f = TypeDesc("float") 185 p = TypeDesc("point") 186 v = TypeDesc("vector") 187 print "float==point?", (f == p) 188 print "vector==point?", (v == p) 189 print "float.equivalent(point)?", f.equivalent(p) 190 print "vector.equivalent(point)?", v.equivalent(p) 191 192 > float==point? False 193 > vector==point? False 194 > float.equivalent(point)? False 195 > vector.equivalent(point)? True 196\end{code} 197\apiend 198 199 200\section{ROI} 201\label{sec:pythonroi} 202 203The \ROI class that describes an image extent or region of interest, 204explained in deail in Section~\ref{sec:ROI}, is replicated for Python. 205 206\apiitem{{\ce ROI} () \\ 207{\ce ROI} (xbegin, xend, ybegin, yend) \\ 208{\ce ROI} (xbegin, xend, ybegin, yend, zbegin, zend) \\ 209{\ce ROI} (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend)} 210Construct an \ROI with the given bounds. The constructor with no 211arguments makes an \ROI that is ``undefined.'' 212 213\noindent Example: 214\begin{code} 215 import OpenImageIO as oiio 216 ... 217 roi = ROI (0, 640, 0, 480, 0, 1, 0, 4) # video res RGBA 218\end{code} 219\apiend 220 221\apiitem{int ROI.{\ce xbegin} \\ 222int ROI.{\ce xend} \\ 223int ROI.{\ce ybegin} \\ 224int ROI.{\ce yend} \\ 225int ROI.{\ce zbegin} \\ 226int ROI.{\ce zend} \\ 227int ROI.{\ce chbegin} \\ 228int ROI.{\ce chend}} 229The basic fields of the \ROI. 230\apiend 231 232\apiitem{ROI ROI.{\ce All}} 233A pre-constructed undefined \ROI. 234\apiend 235 236\apiitem{bool ROI.{\ce defined}} 237{\cf True} if the \ROI is defined, {\cf False} if the \ROI is undefined. 238\apiend 239 240\apiitem{int ROI.{\ce width} \\ 241int ROI.{\ce height} \\ 242int ROI.{\ce depth} \\ 243int ROI.{\ce nchannels}} 244The number of pixels in each dimension, and the number of channels, 245as described by the \ROI. 246\apiend 247 248\apiitem{int ROI.{\ce npixels}} 249The total number of pixels in the region described by the \ROI. 250\apiend 251 252\apiitem{int ROI.{\ce contains} (x, y, z=0, ch=0)} 253Returns {\cf True} if the ROI contains the coordinate. 254\apiend 255 256\apiitem{int ROI.{\ce contains} (other)} 257Returns {\cf True} if the ROI {\cf other} is entirel contained within 258this ROI. 259\apiend 260 261 262\apiitem{ROI {\ce get_roi} (imagespec) \\ 263ROI {\ce get_roi_full} (imagespec)} 264Returns the \ROI corresponding to the pixel data window of the given 265\ImageSpec, or the display/full window, respectively. 266 267\noindent Example: 268\begin{code} 269 spec = ImageSpec(...) 270 roi = oiio.get_roi(spec) 271\end{code} 272\apiend 273 274\apiitem{{\ce set_roi} (imagespec, roi) \\ 275{\ce set_roi_full} (imagespec, roi)} 276Alter the \ImageSpec's resolution and offset to match the passed \ROI. 277 278\noindent Example: 279\begin{code} 280 # spec is an ImageSpec 281 # The following sets the full (display) window to be equal to the 282 # pixel data window: 283 oiio.set_roi_full (spec, oiio.get_roi(spec)) 284\end{code} 285\apiend 286 287 288\section{ImageSpec} 289\label{sec:pythonimagespec} 290 291The \ImageSpec class that describes an image, explained in deail in 292Section~\ref{sec:ImageSpec}, is replicated for Python. 293 294\apiitem{{\ce ImageSpec} ()\\ 295{\ce ImageSpec} (typedesc) \\ 296{\ce ImageSpec} (xres, yres, nchannels, typedesc) \\ 297{\ce ImageSpec} (roi, typedesc)} 298Constructors of an \ImageSpec. These correspond directly to the constructors 299in the C++ bindings. 300 301\noindent Example: 302\begin{code} 303 import OpenImageIO as oiio 304 ... 305 306 # default ctr 307 s = ImageSpec() 308 309 # construct with known pixel type, unknown resolution 310 s = ImageSpec(oiio.UINT8) 311 312 # construct with known resolution, channels, pixel data type 313 s = ImageSpec(640, 480, 4, "half") 314 315 # construct from an ROI 316 s = ImageSpec (ROI(0,640,0,480,0,1,0,3), TypeFloat) 317\end{code} 318\apiend 319 320\apiitem{ImageSpec.{\ce width}, ImageSpec.{\ce height}, ImageSpec.{\ce depth} \\ 321ImageSpec.{\ce x}, ImageSpec.{\ce y}, ImageSpec.{\ce z}} 322Resolution and offset of the image data ({\cf int} values). 323 324\noindent Example: 325\begin{code} 326 s = ImageSpec (...) 327 print "Data window is ({},{})-({},{})".format (s.x, s.x+s.width-1, 328 s.y, s.y+s.height-1) 329\end{code} 330\apiend 331 332\apiitem{ImageSpec.{\ce full_width}, ImageSpec.{\ce full_height}, ImageSpec.{\ce full_depth} \\ 333ImageSpec.{\ce full_x}, ImageSpec.{\ce full_y}, ImageSpec.{\ce full_z}} 334Resolution and offset of the ``full'' display window ({\cf int} values). 335\apiend 336 337\apiitem{ImageSpec.{\ce tile_width}, ImageSpec.{\ce tile_height}, ImageSpec.{\ce tile_depth}} 338For tiled images, the resolution of the tiles ({\cf int} values). Will be 339{\cf 0} for untiled images. 340\apiend 341 342\apiitem{typedesc ImageSpec.{\ce format}} 343A \TypeDesc describing the pixel data. 344\apiend 345 346\apiitem{int ImageSpec.{\ce nchannels}} 347An {\cf int} giving the number of color channels in the image. 348\apiend 349 350\apiitem{ImageSpec.{\ce channelnames}} 351A tuple of strings containing the names of each color channel. 352\apiend 353 354\apiitem{ImageSpec.{\ce channelformats}} 355If all color channels have the same format, that will be {\cf ImageSpec.format}, 356and {\cf channelformats} will be {\cf None}. However, if there are different 357formats per channel, they will be stored in {\cf channelformats} as a tuple 358of {\cf TypeDesc} objects. 359 360\noindent Example: 361\begin{code} 362 if spec.channelformats == None: 363 print "All color channels are", str(spec.format) 364 else: 365 print "Channel formats: " 366 for t in spec.channelformats: 367 print "\t", t 368\end{code} 369\apiend 370 371\apiitem{ImageSpec.{\ce alpha_channel} \\ 372ImageSpec.{\ce z_channel}} 373The channel index containing the alpha or depth channel, respectively, or 374-1 if either one does not exist or cannot be identified. 375\apiend 376 377\apiitem{ImageSpec.{\ce deep}} 378Hold {\cf True} if the image is a \emph{deep} (multiple samples per pixel) 379image, of {\cf False} if it is an ordinary image. 380\apiend 381 382\apiitem{ImageSpec.{\ce extra_attribs}} 383Direct access to the {\cf extra_attribs} named metadata, appropriate for 384iterating over the entire list rather than searching for a particular named 385value. 386 387\vspace{-10pt} 388\apiitem{len(extra_attribs)} 389\vspace{10pt} 390Returns the number of extra attributes. 391\apiend 392\vspace{-24pt} 393\apiitem{extra_attribs[i].name} 394\vspace{10pt} 395The name of the indexed attribute. 396\apiend 397\vspace{-24pt} 398\apiitem{extra_attribs[i].type} 399\vspace{10pt} 400The type of the indexed attribute, as a \TypeDesc. 401\apiend 402\vspace{-24pt} 403\apiitem{extra_attribs[i].value} 404\vspace{10pt} 405The value of the indexed attribute. 406\apiend 407 408\noindent Example: 409\begin{code} 410 s = ImageSpec(...) 411 ... 412 print "extra_attribs size is", len(s.extra_attribs) 413 for i in range(len(s.extra_attribs)) : 414 print i, s.extra_attribs[i].name, str(s.extra_attribs[i].type), " :" 415 print "\t", s.extra_attribs[i].value 416 print 417\end{code} 418\apiend 419 420\apiitem{Imagespec.{\ce roi}} 421The ROI describing the pixel data window. 422\apiend 423 424\apiitem{ImageSpec.{\ce roi_full}} 425The ROI describing the ``display window'' (or ``full size''). 426\apiend 427 428\apiitem{ImageSpec.{\ce set_format} (typedesc)} 429Given a \TypeDesc, sets the {\cf format} field and 430clear any per-channel formats in {\cf channelformats}. 431 432\noindent Example: 433\begin{code} 434 s = ImageSpec () 435 s.set_format (TypeDesc("uint8")) 436\end{code} 437\apiend 438 439\apiitem{ImageSpec.{\ce default_channel_names} ()} 440Sets {\cf channel_names} to the default names given the value of 441the {\cf nchannels} field. 442\apiend 443 444\apiitem{int ImageSpec.{\ce channelindex} (name)} 445Return (as an int) the index of the channel with the given name, or -1 446if it does not exist. 447\apiend 448 449\apiitem{ImageSpec.{\ce channel_bytes} () \\ 450ImageSpec.{\ce channel_bytes} (channel, native=False)} 451Returns the size of a single channel value, in bytes (as an 452{\cf int}). 453(Analogous to the C++ member functions, see 454Section~\ref{sec:ImageSpecMemberFuncs} for details.) 455\apiend 456 457\apiitem{ImageSpec.{\ce pixel_bytes} () \\ 458ImageSpec.{\ce pixel_bytes} (native=False) \\ 459ImageSpec.{\ce pixel_bytes} (chbegin, chend, native=False)} 460Returns the size of a pixel, in bytes (as an {\cf int}). 461(Analogous to the C++ member functions, see 462Section~\ref{sec:ImageSpecMemberFuncs} for details.) 463\apiend 464 465\apiitem{ImageSpec.{\ce scanline_bytes} (native=False) \\ 466ImageSpec.{\ce tile_bytes} (native=False) \\ 467ImageSpec.{\ce image_bytes} (native=False)} 468Returns the size of a scanline, tile, or the full image, in bytes (as an 469{\cf int}). (Analogous to the C++ member functions, see 470Section~\ref{sec:ImageSpecMemberFuncs} for details.) 471\apiend 472 473\apiitem{ImageSpec.{\ce tile_pixels} () \\ 474ImageSpec.{\ce image_pixels} ()} 475Returns the number of pixels in a tile or the full image, respectively 476(as an {\cf int}). (Analogous to the C++ member functions, see 477Section~\ref{sec:ImageSpecMemberFuncs} for details.) 478\apiend 479 480\apiitem{ImageSpec.{\ce erase_attribute} (name, searchtype=TypeUnknown,\\ 481\bigspc\bigspc\spc casesensitive=False)} 482Remove any specified attributes matching the regular expression {\cf name} 483from the list of extra_attribs. 484\apiend 485 486\apiitem{ImageSpec.{\ce attribute} (name, int) \\ 487ImageSpec.{\ce attribute} (name, float) \\ 488ImageSpec.{\ce attribute} (name, string) \\ 489ImageSpec.{\ce attribute} (name, typedesc, data) \\} 490Sets a metadata value in the {\cf extra_attribs}. If the metadata item 491is a single {\cf int}, {\cf float}, or {\cf string}, you can pass it 492directly. For other types, you must pass the \TypeDesc and then the 493data (for aggregate types or arrays, pass multiple values as a tuple). 494 495\noindent Example: 496\begin{code} 497 s = ImageSpec (...) 498 s.attribute ("foo_str", "blah") 499 s.attribute ("foo_int", 14) 500 s.attribute ("foo_float", 3.14) 501 s.attribute ("foo_vector", TypeDesc.TypeVector, (1, 0, 11)) 502 s.attribute ("foo_matrix", TypeDesc.TypeMatrix, 503 (1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1)) 504\end{code} 505\apiend 506 507\apiitem{ImageSpec.{\ce getattribute} (name) \\ 508ImageSpec.{\ce getattribute} (name, typedesc)} 509Retrieves a named metadata value from {\cf extra_attribs}. The generic 510{\cf getattribute()} function returns it regardless of type, or {\cf None} 511if the attribute does not exist. The typed variety will only succeed 512if the attribute is actually of that type specified. 513 514\noindent Example: 515\begin{code} 516 foo = s.getattribute ("foo") # None if not found 517 foo = s.getattribute ("foo", oiio.FLOAT) # None if not found AND float 518\end{code} 519\apiend 520 521\apiitem{ImageSpec.{\ce get_int_attribute} (name, defaultval=0) \\ 522ImageSpec.{\ce get_float_attribute} (name, defaultval=0.0) \\ 523ImageSpec.{\ce get_string_attribute} (name, defaultval="")} 524Retrieves a named metadata value from {\cf extra_attribs}, if it is 525found and is of the given type; returns the default value (or a passed 526value) if not found. 527 528\noindent Example: 529\begin{code} 530 # If "foo" is not found, or if it's not an int, return 0 531 foo = s.get_int_attribute ("foo") 532 533 # If "foo" is not found, or if it's not a string, return "blah" 534 foo = s.get_string_attribute ("foo", "blah") 535\end{code} 536\apiend 537 538\apiitem{ImageSpec{\ce [name]}} 539\NEW % 2.1 540Retrieve or set metadata using a dictionary-like syntax, rather than 541{\cf attribute()} and {\cf getattribute()}. This is best illustrated by 542example: 543 544\begin{code} 545 comp = spec["Compression"] 546 # Same as: comp = spec.getattribute("Compression") 547 548 spec["Compression"] = comp 549 # Same as: spec.attribute("Compression", comp) 550\end{code} 551\apiend 552 553%\apiitem{static ImageSpec.{\ce metadata_val} (paramval, human=False)} 554%For a \ParamValue, format its value as a string. 555%\apiend 556 557\apiitem{ImageSpec.{\ce serialize} (format="text", verbose="Detailed")} 558Return a string containing the serialization of the \ImageSpec. The {\cf format} 559may be either \qkw{text} or \qkw{XML}. The {\cf verbose} may be one of 560\qkw{brief}, \qkw{detailed}, or \qkw{detailedhuman}. 561\apiend 562 563\apiitem{ImageSpec.{\ce to_xml} ()} 564Equivalent to {\cf serialize ("xml", "detailedhuman")}. 565\apiend 566 567\apiitem{ImageSpec.{\ce from_xml} (xml)} 568Initializes the \ImageSpec from the information in the string {\cf xml} 569containing an XML-serialized \ImageSpec. 570\apiend 571 572\apiitem{ImageSpec.{\ce channel_name} (chan)} 573Returns a string containing the name of the channel with index {\cf chan}. 574\apiend 575 576\apiitem{ImageSpec.{\ce channelindex} (name)} 577Return the integer index of the channel with the given {\cf name}, or 578-1 if the name is not a name of one of the channels. 579\apiend 580 581\apiitem{ImageSpec.{\ce channelformat} (chan)} 582Returns a \TypeDesc of the channel with index {\cf chan}. 583\apiend 584 585\apiitem{ImageSpec.{\ce get_channelformats} ()} 586Returns a tuple containing all the channel formats. 587\apiend 588 589\apiitem{ImageSpec.{\ce valid_tile_range} (xbegin, xend, ybegin, yend, zbegin, zend)} 590Returns {\cf True} if the given tile range exactly covers a set of tiles, or 591{\cf False} if it isn't (or if the image is not tiled). 592\apiend 593 594\apiitem{ImageSpec.{\ce copy_dimensions} (other)} 595Copies from \ImageSpec {\cf other} only the fields describing the size 596and data types, but not the arbitrary named metadata or channel names. 597\apiend 598 599\apiitem{ImageSpec.{\ce undefined}()} 600Returns {\cf True} for a newly initialized (undefined) \ImageSpec. 601\apiend 602 603\newpage 604\subsection*{Example: Header info} 605 606Here is an illustrative example of the use of \ImageSpec, a working Python 607function that opens a file and prints all the relevant header 608information: 609 610\begin{tinycode} 611#!/usr/bin/env python 612import OpenImageIO as oiio 613 614# Print the contents of an ImageSpec 615def print_imagespec (spec, subimage=0, mip=0) : 616 if spec.depth <= 1 : 617 print (" resolution %dx%d%+d%+d" % (spec.width, spec.height, spec.x, spec.y)) 618 else : 619 print (" resolution %dx%d%x%d+d%+d%+d" % 620 (spec.width, spec.height, spec.depth, spec.x, spec.y, spec.z)) 621 if (spec.width != spec.full_width or spec.height != spec.full_height 622 or spec.depth != spec.full_depth) : 623 if spec.full_depth <= 1 : 624 print (" full res %dx%d%+d%+d" % 625 (spec.full_width, spec.full_height, spec.full_x, spec.full_y)) 626 else : 627 print (" full res %dx%d%x%d+d%+d%+d" % 628 (spec.full_width, spec.full_height, spec.full_depth, 629 spec.full_x, spec.full_y, spec.full_z)) 630 if spec.tile_width : 631 print (" tile size %dx%dx%d" % 632 (spec.tile_width, spec.tile_height, spec.tile_depth)) 633 else : 634 print " untiled" 635 if mip >= 1 : 636 return 637 print " " + str(spec.nchannels), "channels:", spec.channelnames 638 print " format = ", str(spec.format) 639 if len(spec.channelformats) > 0 : 640 print " channelformats = ", spec.channelformats 641 print " alpha channel = ", spec.alpha_channel 642 print " z channel = ", spec.z_channel 643 print " deep = ", spec.deep 644 for i in spec.extra_attribs) : 645 if type(i.value) == str : 646 print " ", i.name, "= \"" + i.value + "\"" 647 else : 648 print " ", i.name, "=", i.value 649 650 651def poor_mans_iinfo (filename) : 652 input = ImageInput.open (filename) 653 if not input : 654 print 'Could not open "' + filename + '"' 655 print "\tError: ", oiio.geterror() 656 return 657 print 'Opened "' + filename + '" as a ' + input.format_name() 658 sub = 0 659 mip = 0 660 while True : 661 if sub > 0 or mip > 0 : 662 print "Subimage", sub, "MIP level", mip, ":" 663 print_imagespec (input.spec(), mip=mip) 664 mip = mip + 1 665 if input.seek_subimage (sub, mip) : 666 continue # proceed to next MIP level 667 else : 668 sub = sub + 1 669 mip = 0 670 if input.seek_subimage (sub, mip) : 671 continue # proceed to next subimage 672 break # no more MIP levels or subimages 673 input.close () 674\end{tinycode} 675 676 677\section{DeepData} 678\label{sec:pythondeepdata} 679 680The \DeepData class describing ``deep'' image data (multiple depth 681sample per pixel), which is explained in deail in 682Section~\ref{sec:imageinput:deepdata}, is replicated for Python. 683 684\apiitem{{\ce DeepData} ()} 685Constructs a \DeepData object. It needs to have its {\cf init()} and 686{\cf alloc()} methods called before it can hold any meaningful data. 687\apiend 688 689\apiitem{DeepData.{\ce init} (npixels, nchannels, channeltypes, channelnames)} 690Initializes this \DeepData to hold {\cf npixels} total pixels, with 691{\cf nchannels} color channels. The data types of the channels are 692described by {\cf channeltypes}, a tuple of \TypeDesc values (one per 693channel), and the names are provided in a tuple of {\cf string}s 694{\cf channelnames}. After calling {\cf init}, you still need to set the number of 695samples for each pixel (using {\cf set_nsamples}) and then call {\cf alloc()} 696to actually allocate the sample memory. 697\apiend 698 699\apiitem{bool {\ce DeepData}.initialized ()} 700Returns {\cf True} if the \DeepData is initialized at all. 701\apiend 702 703\apiitem{bool {\ce DeepData}.allocated ()} 704Returns {\cf True} if the \DeepData has already had pixel memory allocated. 705\apiend 706 707\apiitem{DeepData.{\ce pixels}} 708This {\cf int} field constains the total number of pixels in this 709collection of deep data. 710\apiend 711 712\apiitem{DeepData.{\ce channels}} 713This {\cf int} field constains the number of channels. 714\apiend 715 716\apiitem{int DeepData.{\ce A_channel} \\ 717int DeepData.{\ce AR_channel} \\ 718int DeepData.{\ce AG_channel} \\ 719int DeepData.{\ce AB_channel} \\ 720int DeepData.{\ce Z_channel} \\ 721int DeepData.{\ce Zback_channel}} 722The channel index of certain named channels, or -1 if they don't exist. For 723{\cf AR_channel}, {\cf AG_channel}, {\cf AB_channel}, if they don't exist, 724they will contain the value of {\cf A_channel}, and {\cf Zback_channel} will 725contain the value of {\cf Z_channel} if there is no actual {\cf Zback}. 726\apiend 727 728\apiitem{string DeepData.{\ce channelname} (c)} 729Retrieve the name of channel {\cf c}. 730\apiend 731 732\apiitem{TypeDesc DeepData.{\ce channeltype} (c)} 733Retrieve the data type of channel {\cf c}. 734\apiend 735 736\apiitem{int DeepData.{\ce channelsize} (c)} 737Retrieve the size (in bytes) of one datum of channel {\cf c}. 738\apiend 739 740\apiitem{int DeepData.{\ce samplesize} ()} 741Retrieve the packed size (in bytes) of all channels of one sample. 742\apiend 743 744 745\apiitem{DeepData.{\ce set_samples} (pixel, nsamples) \\ 746int DeepData.{\ce samples} (pixel)} 747Set or get the number of samples for a given pixel (specified by integer 748index). 749\apiend 750 751\apiitem{DeepData.{\ce insert_samples} (pixel, samplepos, n) \\ 752int DeepData.{\ce erase_samples} (pixel, samplepos, n)} 753Insert or erase \emph{n} samples starting at the given position of an 754indexed pixel. 755\apiend 756 757\apiitem{DeepData.{\ce set_deep_value} (pixel, channel, sample, value) \\ 758DeepData.{\ce set_deep_value_uint} (pixel, channel, sample, value)} 759Set specific float or unsigned int value of a given pixel, channel, and 760sample index. 761\apiend 762 763\apiitem{DeepData.{\ce deep_value} (pixel, channel, sample, value) \\ 764int DeepData.{\ce deep_value_uint} (pixel, channel, sample)} 765Retrieve the specific value of a given pixel, 766channel, and sample index (for float or uint channels, respectively). 767\apiend 768 769\apiitem{DeepData.{\ce copy_deep_sample} (pixel, sample, src, srcpixel, srcsample)} 770Copy a deep sample from \DeepData {\cf src} into this \DeepData. 771\apiend 772 773\apiitem{DeepData.{\ce copy_deep_pixel} (pixel, src, srcpixel)} 774Copy a deep pixel from \DeepData {\cf src} into this \DeepData. 775\apiend 776 777\apiitem{bool DeepData.{\ce split} (pixel, depth)} 778Split any samples of the pixel that cross {\cf depth}. Return {\cf True} if 779any splits occurred, {\cf False} if the pixel was unmodified. 780\apiend 781 782\apiitem{DeepData.{\ce sort} (pixel)} 783Sort the samples of the pixel by their Z depth. 784\apiend 785 786\apiitem{DeepData.{\ce merge_overlaps} (pixel)} 787Merge any adjacent samples in the pixel that exactly overlap in $z$ 788range. This is only useful if the pixel has previously been split at 789all sample starts and ends, and sorted by depth. 790\apiend 791 792\apiitem{DeepData.{\ce merge_deep_pixels} (pixel, src, srcpixel)} 793Merge the samples of {\cf src}'s pixel into this \DeepData's pixel. 794\apiend 795 796\apiitem{DeepData.{\ce occlusion_cull} (pixel)} 797Eliminate any samples beyond an opaque sample. 798\apiend 799 800\apiitem{float DeepData.{\ce opaque_z} (pixel)} 801For the given pixel index. return the $z$ value at which the pixel reaches 802full opacity. 803\apiend 804 805 806 807\section{ImageInput} 808\label{sec:pythonimageinput} 809 810See Chapter~\ref{chap:imageinput} for detailed explanations of the 811C++ \ImageInput class APIs. The Python APIs are very similar. The biggest 812difference is that in C++, the various {\cf read_*} functions write the 813pixel values into an already-allocated array that belongs to the caller, 814whereas the Python versions allocate and return an array holding the pixel 815values (or {\cf None} if the read failed). 816 817 818\apiitem{ImageInput.{\ce open} (filename) \\ 819ImageInput.{\ce open} (filename, config_imagespec)} 820Creates an \ImageInput object and opens the named file. Returns the 821open \ImageInput upon success, or {\cf None} if it failed to open the 822file (after which, {\cf OpenImageIO.geterror()} will contain an error 823message). In the second form, the optional \ImageSpec argument 824{\cf config} contains attributes that may set certain options when opening 825the file. 826 827\noindent Example: 828\begin{code} 829 input = ImageInput.open ("tahoe.jpg") 830 if input == None : 831 print "Error:", oiio.geterror() 832 return 833\end{code} 834\apiend 835 836\apiitem{bool ImageInput.{\ce close} ()} 837Closes an open image file, returning {\cf True} if successful, {\cf False} 838otherwise. 839 840\noindent Example: 841\begin{code} 842 input = ImageInput.open (filename) 843 ... 844 input.close () 845\end{code} 846\apiend 847 848 849\apiitem{str ImageInput.{\ce format_name} ()} 850Returns the format name of the open file. 851 852\noindent Example: 853\begin{code} 854 input = ImageInput.open (filename) 855 if input : 856 print filename, "was a", input.format_name(), "file." 857 input.close () 858 859\end{code} 860\apiend 861 862\apiitem{ImageSpec ImageInput.{\ce spec} ()} 863Returns the \ImageSpec corresponding to the currently open subimage and 864MIP level of the file. 865 866\noindent Example: 867\begin{code} 868 input = ImageInput.open (filename) 869 spec = input.spec() 870 print "resolution ", spec.width, "x", spec.height 871\end{code} 872\apiend 873 874\apiitem{ImageSpec ImageInput.{\ce spec} (subimage, miplevel=0) \\ 875ImageSpec ImageInput.{\ce spec_dimensions} (subimage, miplevel=0)} 876Returns a copy of the \ImageSpec corresponding to the designated subimage 877and MIP level. Note that {\cf spec()} copies the entire \ImageSpec including 878all metadata, whereas {\cf spec_dimensions()} only copies the dimension 879fields and not any of the arbitrary named metadata (and is thus much less 880expensive). 881\apiend 882 883\apiitem{int ImageInput.{\ce current_subimage} () \\ 884int ImageInput.{\ce current_miplevel} ()} 885Returns the current subimage and/or MIP level of the file. 886\apiend 887 888\apiitem{bool ImageInput.{\ce seek_subimage} (subimage, miplevel)} 889Repositions the file pointer to the given subimage and MIP level within the 890file (starting with {\cf 0}). This function returns {\cf True} upon success, 891{\cf False} upon failure (which may include the file not having the 892specified subimage or MIP level). 893 894\noindent Example: 895\begin{code} 896 input = ImageInput.open (filename) 897 mip = 0 898 while True : 899 ok = input.seek_subimage (0, mip) 900 if not ok : 901 break 902 spec = input.spec() 903 print "MIP level", mip, "is", spec.width, "x", spec.height 904\end{code} 905\apiend 906 907\apiitem{ImageInput.{\ce read_image} (format="float") \\ 908ImageInput.{\ce read_image} (chbegin, chend, format="float") \\ 909ImageInput.{\ce read_image} (subimage, miplevel, chbegin, chend, format="float")} 910 911Read the entire image and return the pixels as a NumPy array of values of 912the given {\cf type} (described by a \TypeDesc or a string, float by 913default). If the {\cf type} is {\cf TypeUnknown}, the pixels will be 914returned in the native format of the file. If an error occurs, {\cf None} 915will be returned. 916 917For a normal (2D) image, the array returned will be 3D indexed as 918{\cf [y][x][channel]}. For 3D volumetric images, the array returned will be 9194D with shape indexed as {\cf [z][y][x][channel]}. 920 921\noindent Example: 922\begin{code} 923 input = ImageInput.open (filename) 924 spec = input.spec () 925 pixels = input.read_image () 926 print "The first pixel is", pixels[0][0] 927 print "The second pixel is", pixels[0][1] 928 input.close () 929\end{code} 930\apiend 931 932\apiitem{ndarray ImageInput.{\ce read_scanline} (y, z, format="float")} 933Read scanline number {\cf y} from depth plane {\cf z} from the open file, 934returning the pixels as a NumPy array of values of 935the given {\cf type} (described by a \TypeDesc or a string, float by 936default). If the {\cf type} is {\cf TypeUnknown}, the pixels will be 937returned in the native format of the file. If an error occurs, {\cf None} 938will be returned. 939 940The pixel array returned be 2D, indexed as {\cf [x][channel]}. 941 942\noindent Example: 943\begin{code} 944 input = ImageInput.open (filename) 945 spec = input.spec () 946 if spec.tile_width == 0 : 947 for y in range(spec.y, spec.y+spec.height) : 948 pixels = input.read_scanline (y, spec.z, "float") 949 # process the scanline 950 else : 951 print "It's a tiled file" 952 input.close () 953\end{code} 954\apiend 955 956\apiitem{ndarray ImageInput.{\ce read_tile} (x, y, z, format="float")} 957Read the tile whose upper left corner is pixel {\cf (x,y,z)} from the open 958file, returning the pixels as a NumPy array of values of 959the given {\cf type} (described by a \TypeDesc or a string, float by 960default). If the {\cf type} is {\cf TypeUnknown}, the pixels will be 961returned in the native format of the file. If an error occurs, {\cf None} 962will be returned. 963 964For a normal (2D) image, the array of tile pixels returned will be 3D 965indexed as {\cf [y][x][channel]}. For 3D volumetric images, the array 966returned will be 4D with shape indexed as {\cf [z][y][x][channel]}. 967 968\noindent Example: 969\begin{code} 970 input = ImageInput.open (filename) 971 spec = input.spec () 972 if spec.tile_width > 0 : 973 for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) : 974 for y in range(spec.y, spec.y+spec.height, spec.tile_height) : 975 for x in range(spec.x, spec.x+spec.width, spec.tile_width) : 976 pixels = input.read_tile (x, y, z, oiio.FLOAT) 977 # process the tile 978 else : 979 print "It's a scanline file" 980 input.close () 981\end{code} 982\apiend 983 984\apiitem{ndarray ImageInput.{\ce read_scanlines} (subimage, miplevel, \\ 985\bigspc\bigspc\spc ybegin, yend, z, chbegin, chend, format="float") \\ 986ndarray ImageInput.{\ce read_scanlines} (ybegin, yend, z, chbegin, chend, \\ 987\bigspc\bigspc\spc format="float") \\ 988ndarray ImageInput.{\ce read_tiles} (xbegin, xend, ybegin, yend, zbegin, zend, \\ 989 \bigspc\bigspc\spc chbegin, chend, format="float") \\ 990ndarray ImageInput.{\ce read_tiles} (subimage, miplevel, \\ 991 \bigspc\bigspc\spc xbegin, xend, ybegin, yend, zbegin, zend, format="float")} 992Similar to the C++ routines, these functions read multiple scanlines or 993tiles at once, which in some cases may be more efficient than reading 994each scanline or tile separately. Additionally, they allow you to read only 995a subset of channels. 996 997For normal 2D images, both {\cf read_scanlines} and {\cf read_tiles} will 998return a 3D array indexed as {\cf [z][y][x][channel]}. 999 1000For 3D volumetric images, both {\cf read_scanlines} will return a 3D array 1001indexed as {\cf [y][x][channel]}, and {\cf read_tiles} will return a 4D 1002array indexed as {\cf [z][y][x][channel]}, 1003 1004\noindent Example: 1005\begin{code} 1006 input = ImageInput.open (filename) 1007 spec = input.spec () 1008 1009 # Read the whole image, the equivalent of 1010 # pixels = input.read_image (type) 1011 # but do it using read_scanlines or read_tiles: 1012 if spec.tile_width == 0 : 1013 pixels = input.read_scanlines (spec.y, spec.y+spec.height, 0, 1014 0, spec.nchannels) 1015 else : 1016 pixels = input.read_tiles (spec.x, spec.x+spec.width, 1017 spec.y, spec.y+spec.height, 1018 spec.z, spec.z+spec.depth, 1019 0, spec.nchannels) 1020\end{code} 1021\apiend 1022 1023\apiitem{DeepData ImageInput.{\ce read_native_deep_scanlines} (subimage, miplevel, \\ 1024\bigspc\bigspc ybegin, yend, z, chbegin, chend) \\ 1025DeepData ImageInput.{\ce read_native_deep_tiles} (subimage, miplevel, \\ 1026\bigspc\bigspc xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend) \\ 1027DeepData ImageInput.{\ce read_native_deep_image} (subimage=0, miplevel=0)} 1028Read a collection of scanlines, tiles, or an entire image of ``deep'' pixel 1029data from the specified subimage and MIP level. The begin/end coordinates 1030are all integer values. The value returned will be a \DeepData if the read 1031succeeds, or {\cf None} if the read fails. 1032 1033These methods are guaranteed to be thread-safe against simultaneous calls to 1034any of the other other {\cf read_native} calls that take an explicit 1035subimage/miplevel. 1036\apiend 1037 1038\apiitem{str ImageInput.{\ce geterror} ()} 1039Retrieves the error message from the latest failed operation on an 1040ImageInput. 1041 1042\noindent Example: 1043\begin{code} 1044 input = ImageInput.open (filename) 1045 if not input : 1046 print "Open error:", oiio.geterror() 1047 # N.B. error on open must be retrieved with the global geterror(), 1048 # since there is no ImageInput object! 1049 else : 1050 pixels = input.read_image (oiio.FLOAT) 1051 if not pixels : 1052 print "Read_image error:", input.geterror() 1053 input.close () 1054\end{code} 1055\apiend 1056 1057\newpage 1058\subsection*{Example: Reading pixel values from a file to find min/max} 1059 1060\begin{code} 1061#!/usr/bin/env python 1062import OpenImageIO as oiio 1063 1064def find_min_max (filename) : 1065 input = ImageInput.open (filename) 1066 if not input : 1067 print 'Could not open "' + filename + '"' 1068 print "\tError: ", oiio.geterror() 1069 return 1070 spec = input.spec() 1071 nchans = spec.nchannels 1072 pixels = input.read_image() 1073 if not pixels : 1074 print "Could not read:", input.geterror() 1075 return 1076 input.close() # we're done with the file at this point 1077 minval = pixels[0][0] # initialize to the first pixel value 1078 maxval = pixels[0][0] 1079 for y in range(spec.height) : 1080 for x in range(spec.width) : 1081 p = pixels[y][x] 1082 for c in range(nchans) : 1083 if p[c] < minval[c] : 1084 minval[c] = p[c] 1085 if p[c] > maxval[c] : 1086 maxval[c] = p[c] 1087 print "Min values per channel were", minval 1088 print "Max values per channel were", maxval 1089\end{code} 1090\newpage 1091 1092 1093\section{ImageOutput} 1094\label{sec:pythonimageoutput} 1095 1096See Chapter~\ref{chap:imageoutput} for detailed explanations of the 1097C++ \ImageOutput class APIs. The Python APIs are very similar. 1098 1099\apiitem{ImageOutput ImageOutput.{\ce create} (filename, plugin_searchpath="")} 1100 1101Create a new \ImageOutput capable of writing the named file format (which may 1102also be a file name, with the type deduced from the extension). There 1103is an optional parameter giving an colon-separated search path for finding 1104\ImageOutput plugins. The function returns an \ImageOutput object, or 1105{\cf None} upon error (in which case, {OpenImageIO.geterror()} may be used 1106to retrieve the error message). 1107 1108\noindent Example: 1109\begin{code} 1110 import OpenImageIO as oiio 1111 output = ImageOutput.create ("myfile.tif") 1112 if not output : 1113 print "Error:", oiio.geterror() 1114\end{code} 1115\apiend 1116 1117\apiitem{str ImageOutput.{\ce format_name} ()} 1118The file format name of a created \ImageOutput. 1119 1120\noindent Example: 1121\begin{code} 1122 output = ImageOutput.create (filename) 1123 if output : 1124 print "Created output", filename, "as a", output.format_name() 1125\end{code} 1126\apiend 1127 1128\apiitem{int ImageOutput.{\ce supports} (feature)} 1129For a created \ImageOutput, returns {\cf True} if the file format supports 1130the named feature (such as \qkw{tiles}, \qkw{mipmap}, etc., see 1131Section~\ref{sec:supportsfeaturelist} for the full list), or {\cf False} 1132if this file format does not support the feature. 1133 1134\noindent Example: 1135\begin{code} 1136 output = ImageOutput.create (filename) 1137 if output : 1138 print output.format_name(), "supports..." 1139 print "tiles?", output.supports("tiles") 1140 print "multi-image?", output.supports("multiimage") 1141 print "MIP maps?", output.supports("mipmap") 1142 print "per-channel formats?", output.supports("channelformats") 1143\end{code} 1144\apiend 1145 1146\apiitem{bool ImageOutput.{\ce open} (filename, spec, mode="Create")} 1147Opens the named output file, with an \ImageSpec describing the image to 1148be output. The {\cf mode} may be one of \qkw{create}, \qkw{AppendSubimage}, 1149or \qkw{AppendMIPLevel}. 1150See Section~\ref{sec:imageoutputopen} for details. Returns {\cf True} 1151upon success, {\cf False} upon failure (error messages retrieved via 1152{\cf ImageOutput.geterror()}.) 1153 1154\noindent Example: 1155\begin{code} 1156 output = ImageOutput.create (filename) 1157 if not output : 1158 print "Error:", oiio.geterror() 1159 spec = ImageSpec (640, 480, 3, "uint8") 1160 ok = output.open (filename, spec) 1161 if not ok : 1162 print "Could not open", filename, ":", output.geterror() 1163\end{code} 1164\apiend 1165 1166\apiitem{bool ImageOutput.{\ce open} (filename, (imagespec, ...))} 1167This variety of {\cf open()} is used specifically for multi-subimage files. 1168A \emph{tuple} of \ImageSpec objects is passed, one for each subimage 1169that will be written to the file. After each subimage is written, then 1170a regular call to {\cf open(name, newspec, {\ce AppendSubimage})} moves 1171on to the next subimage. 1172\apiend 1173 1174\apiitem{bool ImageOutput.{\ce close} ()} 1175Closes an open output. 1176\apiend 1177 1178\apiitem{ImageSpec ImageOutput.{\ce spec} ()} 1179Retrieves the \ImageSpec of the currently-open output image. 1180\apiend 1181 1182\apiitem{bool ImageOutput.{\ce write_image} (pixels)} 1183Write the currently opened image all at once. The {\cf pixels} parameter 1184should be a Numpy {\cf ndarray} containing data elements indexed as 1185{\cf [y][x][channel]} for normal 2D images, or for 3D volumetric images, 1186as {\cf [z][y][x][channel]}, in other words, exactly matching the shape of 1187array returned by {\cf ImageInput.read_image}. (It will also work fine if 1188the array is 1D ``flattened'' version, as long as it contains the correct 1189total number of values.) The data type is deduced from the contents of the 1190array itself. Returns {\cf True} upon success, {\cf False} upon failure. 1191 1192\noindent Example: 1193\begin{code} 1194 # This example reads a scanline file, then converts it to tiled 1195 # and writes to the same name. 1196 1197 input = ImageInput.open (filename) 1198 spec = input.spec () 1199 pixels = input.read_image () 1200 input.close () 1201 1202 output = ImageOutput.create (filename) 1203 if output.supports("tiles") : 1204 spec.tile_width = 64 1205 spec.tile_height = 64 1206 output.open (filename, spec) 1207 output.write_image (pixels) 1208 output.close () 1209\end{code} 1210\apiend 1211 1212\apiitem{bool ImageOutput.{\ce write_scanline} (y, z, pixels) \\ 1213bool ImageOutput.{\ce write_scanlines} (ybegin, yend, z, pixels)} 1214 1215Write one or many scanlines to the currently open file. 1216Returns {\cf True} upon success, {\cf False} upon failure. 1217 1218The {\cf pixels} parameter 1219should be a Numpy {\cf ndarray} containing data elements indexed as 1220{\cf [x][channel]} for {\cf write_scanline} or as {\cf [y][x][channels} 1221for {\cf write_scanlines}, exactly matching the shape returned by 1222{\cf ImageInput.read_scanline} or {\cf ImageInput.read_scanlines}. 1223(It will also work fine if the array is 1D ``flattened'' version, as long 1224as it contains the correct total number of values.) 1225 1226\noindent Example: 1227\begin{code} 1228 # Copy a TIFF image to JPEG by copying scanline by scanline. 1229 input = ImageInput.open ("in.tif") 1230 spec = input.spec () 1231 output = ImageOutput.create ("out.jpg") 1232 output.open (filename, spec) 1233 for z in range(spec.z, spec.z+spec.depth) : 1234 for y in range(spec.y, spec.y+spec.height) : 1235 pixels = input.read_scanline (y, z) 1236 output.write_scanline (y, z, pixels) 1237 output.close () 1238 input.close () 1239 1240 # The same example, but copying a whole "plane" of scanlines at a time: 1241 ... 1242 for z in range(spec.z, spec.z+spec.depth) : 1243 pixels = input.read_scanlines (spec.y, spec.y+spec.height, z) 1244 output.write_scanlines (spec.y, spec.y+spec.height, z, pixels) 1245 ... 1246\end{code} 1247\apiend 1248 1249\apiitem{bool ImageOutput.{\ce write_tile} (x, y, z, pixels) \\ 1250bool ImageOutput.{\ce write_tiles} (xbegin, xend, ybegin, yend, zbegin, zend, pixels)} 1251 1252Write one or many tiles to the currently open file. 1253Returns {\cf True} upon success, {\cf False} upon failure. 1254 1255The {\cf pixels} parameter 1256should be a Numpy {\cf ndarray} containing data elements indexed as 1257{\cf [y][x][channel]} for normal 2D images, or as {\cf [z][y][x][channels} 12583D volumetric images, exactly matching the shape returned by 1259{\cf ImageInput.read_tile} or {\cf ImageInput.read_tiles}. 1260(It will also work fine if the array is 1D ``flattened'' version, as long 1261as it contains the correct total number of values.) 1262 1263\noindent Example: 1264\begin{code} 1265 input = ImageInput.open (in_filename) 1266 spec = input.spec () 1267 output = ImageOutput.create (out_filename) 1268 output.open (out_filename, spec) 1269 for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) : 1270 for y in range(spec.y, spec.y+spec.height, spec.tile_height) : 1271 for x in range(spec.x, spec.x+spec.width, spec.tile_width) : 1272 pixels = input.read_tile (x, y, z) 1273 output.write_tile (x, y, z, pixels) 1274 output.close () 1275 input.close () 1276 1277 # The same example, but copying a whole row of of tiles at a time: 1278 ... 1279 for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) : 1280 for y in range(spec.y, spec.y+spec.height, spec.tile_height) : 1281 pixels = input.read_tiles (spec.x, spec.x+spec.width, 1282 y, y+tile_width, z, z+tile_width) 1283 output.write_tiles (spec.x, spec.x+spec.width, 1284 y, y+tile_width, z, z+tile_width, pixels) 1285 ... 1286\end{code} 1287\apiend 1288 1289\apiitem{bool ImageOutput.{\ce write_deep_scanlines} (ybegin, yend, z, deepdata) \\ 1290bool ImageOutput.{\ce write_deep_tiles} (xbegin, xend, ybegin, yend, \\ 1291\bigspc\bigspc\bigspc zbegin, zend, deepdata) \\ 1292bool ImageOutput.{\ce write_deep_image} (deepdata)} 1293 1294Write a collection of scanlines, tiles, or an entire image of ``deep'' 1295pixel data. The begin/end coordinates are all integer values, and 1296{\cf deepdata} should be a \DeepData. 1297\apiend 1298 1299\apiitem{bool ImageOutput.{\ce copy_image} (imageinput)} 1300Copy the current image of the open input to the open output. (The reason 1301this may be preferred in some circumstances is that, if input and 1302output were the same kind of input file format, they may have a special 1303efficient technique to copy pixels unaltered, for example by avoiding the 1304decompression/recompression round trip.) 1305 1306\noindent Example: 1307\begin{code} 1308 input = ImageInput.open (in_filename) 1309 spec = input.spec () 1310 output = ImageOutput.create (out_filename) 1311 output.open (filename, spec) 1312 output.copy_image (input) 1313 output.close () 1314 input.close () 1315\end{code} 1316\apiend 1317 1318\apiitem{str ImageOuput.{\ce geterror} ()} 1319Retrieves the error message from the latest failed operation on an open 1320file. 1321 1322\noindent Example: 1323\begin{code} 1324 output = ImageOutput.create (filename) 1325 if not output : 1326 print "Create error:", oiio.geterror() 1327 # N.B. error on create must be retrieved with the global geterror(), 1328 # since there is no ImageOutput object! 1329 else : 1330 ok = output.open (filename, spec) 1331 if not ok : 1332 print "Open error:", output.geterror() 1333 ok = output.write_image (pixels) 1334 if not ok : 1335 print "Write error:", output.geterror() 1336 output.close () 1337\end{code} 1338\apiend 1339 1340 1341 1342\section{ImageBuf} 1343\label{sec:pythonimagebuf} 1344 1345See Chapter~\ref{chap:imagebuf} for detailed explanations of the 1346C++ \ImageBuf class APIs. The Python APIs are very similar. 1347 1348\apiitem{ImageBuf {\ce ImageBuf} ()} 1349Construct a new, empty \ImageBuf. The \ImageBuf is uninitialized and is 1350awaiting a call to {\cf reset()} or {\cf copy()} before it is useful. 1351\apiend 1352 1353\apiitem{ImageBuf {\ce ImageBuf} (filename) \\ 1354ImageBuf {\ce ImageBuf} (filename, subimage, miplevel)} 1355 1356Construct a read-only \ImageBuf that will read from the named file. 1357Optionally, a specific subimage or MIP level may be specified (defaulting to 13580). 1359 1360\noindent Example: 1361\begin{code} 1362 import OpenImageIO as oiio 1363 ... 1364 buf = ImageBuf ("grid.tif") 1365\end{code} 1366\apiend 1367 1368\apiitem{ImageBuf {\ce ImageBuf} (imagespec, zero = True)} 1369 1370Construct a writable \ImageBuf of the dimensions and data format specified 1371by an \ImageSpec. The pixels will be initialized to black/empty values if 1372{\cf zero} is True, otherwise the pixel values will remain uninitialized. 1373 1374\noindent Example: 1375\begin{code} 1376 spec = ImageSpec (640, 480, 3, "float") 1377 buf = ImageBuf (spec) 1378\end{code} 1379\apiend 1380 1381\apiitem{ImageBuf.{\ce clear} ()} 1382Resets the \ImageBuf to a pristine state identical to that of a freshly 1383constructed \ImageBuf using the default constructor. 1384 1385\noindent Example: 1386\begin{code} 1387 buf = ImageBuf (...) 1388 1389 # The following two commands are equivalent: 1390 buf = ImageBuf() # 1 - assign a new blank ImageBuf 1391 buf.clear() # 2 - clear the existing ImageBuf 1392\end{code} 1393\apiend 1394 1395\apiitem{ImageBuf.{\ce reset} (filename, subimage=0, miplevel=0, config=ImageSpec())} 1396Restore the \ImageBuf to a newly-constructed state, to read from 1397a filename (optionally specifying a subimage, MIP level, and/or 1398a ``configuration'' \ImageSpec). 1399\apiend 1400 1401\apiitem{ImageBuf.{\ce reset} (imagespec, zero = True)} 1402Restore the \ImageBuf to the newly-constructed state of a writable 1403\ImageBuf specified by an \ImageSpec. 1404The pixels will be iniialized to black/empty if {\cf zero} is True, 1405otherwise the pixel values will remain uninitialized. 1406\apiend 1407 1408\apiitem{bool ImageBuf.{\ce read} (subimage=0, miplevel=0, force=False, convert=oiio.UNKNOWN) \\ 1409bool ImageBuf.{\ce read} (subimage, miplevel, chbegin, chend, force, convert)} 1410Explicitly read the image from the file (of a file-reading \ImageBuf), optionally 1411specifying a particular subimage, MIP level, and channel range. If {\cf force} is {\cf True}, 1412will force an allocation of memory and a full read (versus the default of 1413relying on an underlying \ImageCache). If {\cf convert} is not 1414the default of {\cf UNKNOWN}, it will force the \ImageBuf to convert the 1415image to the specified data format (versus keeping it in the native 1416format or relying on the \ImageCache to make a data formatting decision). 1417 1418Note that a call to {\cf read()} is not necessary --- any \ImageBuf API call 1419that accesses pixel values will trigger a file read if it has not yet been 1420done. An explicit {\cf read()} is generally only needed to change the 1421subimage or miplevel, or to force an in-buffer read or format conversion. 1422 1423The {\cf read()} method will return {\cf True} for success, or {\cf False} 1424if the read could not be performed (in which case, a {\cf geterror()} call 1425will retrieve the specific error message). 1426 1427\noindent Example: 1428\begin{code} 1429 buf = ImageBuf ("mytexture.exr") 1430 buf.read (0, 2, True) 1431 # That forces an allocation and read of MIP level 2 1432\end{code} 1433\apiend 1434 1435\apiitem{bool ImageBuf.{\ce init_spec} (filename, subimage=0, miplevel=0)} 1436 1437Explicitly read just the header from a file-reading \ImageBuf (if the header 1438has not yet been read), optionally specifying a particular subimage and MIP 1439level. The {\cf init_spec()} method will return {\cf True} for success, or 1440{\cf False} if the read could not be performed (in which case, a {\cf 1441geterror()} call will retrieve the specific error message). 1442 1443Note that a call to {\cf init_spec()} is not necessary --- any \ImageBuf API 1444call that accesses the spec will read it automatically it has not yet been 1445done. 1446\apiend 1447 1448\apiitem{bool ImageBuf.{\ce write} (filename, dtype="", fileformat="")} 1449Write the contents of the \ImageBuf to the named file. Optionally, 1450{\cf dtype} can override the pixel data type (by default, the pixel data 1451type of the buffer), and {\cf fileformat} can specify a particular file 1452format to use (by default, it will infer it from the extension of the file 1453name). 1454 1455\noindent Example: 1456\begin{code} 1457 # No-frills conversion of a TIFF file to JPEG 1458 buf = ImageBuf ("in.tif") 1459 buf.write ("out.jpg") 1460 1461 # Convert to uint16 TIFF 1462 buf = ImageBuf ("in.exr") 1463 buf.write ("out.tif", "uint16") 1464\end{code} 1465\apiend 1466 1467\apiitem{bool ImageBuf.{\ce make_writable} (keep_cache_type = false)} 1468Force the \ImageBuf to be writable. That means that if it was previously 1469backed by an \ImageCache (storage was {\cf IMAGECACHE}), it will force a 1470full read so that the whole image is in local memory. 1471\apiend 1472 1473 1474\apiitem{bool ImageBuf.{\ce set_write_format} (format=oiio.UNKNOWN) \\ 1475bool ImageBuf.{\ce set_write_tiles} (width=0, height=0, depth=0)} 1476Override the data format or tile size in a subsequent call to {\cf write()}. 1477The {\cf format}argument to {\cf set_write_format} may be either a single 1478data type description for all channels, or a tuple giving the data type for 1479each channel in order. 1480 1481\noindent Example: 1482\begin{code} 1483 # Conversion to a tiled unsigned 16 bit integer file 1484 buf = ImageBuf ("in.tif") 1485 buf.set_write_format ("uint16") 1486 buf.set_write_tiles (64, 64) 1487 buf.write ("out.tif") 1488\end{code} 1489\apiend 1490 1491\apiitem{ImageSpec ImageBuf.{\ce spec}() \\ 1492ImageSpec ImageBuf.{\ce nativespec}()} 1493{\cf ImageBuf.spec()} returns the \ImageSpec that describes the contents of 1494the \ImageBuf. {\cf ImageBuf.nativespec()} returns an \ImageSpec that 1495describes the contents of the file that the \ImageBuf was read from (this 1496may differ from {\cf ImageBuf.spec()} due to format conversions, or any 1497changes made to the \ImageBuf after the file was read, such as adding 1498metadata). 1499 1500Handy rule of thumb: {\cf spec()} describes the buffer, {\cf nativespec()} 1501describes the original file it came from. 1502 1503\noindent Example: 1504\begin{code} 1505 buf = ImageBuf ("in.tif") 1506 print "Resolution is", buf.spec().width, "x", buf.spec().height 1507\end{code} 1508\apiend 1509 1510\apiitem{ImageSpec ImageBuf.{\ce specmod}()} 1511{\cf ImageBuf.specmod()} provides writable access to the \ImageSpec that 1512describes the contents of the \ImageBuf. Be very careful! It is safe 1513to modify certain metadata, but if you change the data format or resolution 1514fields, you will get the chaos you deserve. 1515 1516\noindent Example: 1517\begin{code} 1518 # Read an image, add a caption metadata, write it back out in place 1519 buf = ImageBuf ("file.tif") 1520 buf.specmod().attribute ("ImageDescription", "my photo") 1521 buf.write ("file.tif") 1522\end{code} 1523\apiend 1524 1525\apiitem{str ImageBuf.{\ce name} \\ 1526str ImageBuf.{\ce file_format_name}} 1527The file name and name of the file format of the image. 1528\apiend 1529 1530\apiitem{int ImageBuf.{\ce subimage} \\ 1531int ImageBuf.{\ce miplevel} \\ 1532int ImageBuf.{\ce nsubimages} \\ 1533int ImageBuf.{\ce nmiplevels}} 1534Several fields giving information about the current subimage and MIP 1535level, and the total numbers thereof in the file. 1536\apiend 1537 1538\apiitem{int ImageBuf.{\ce xbegin} \\ 1539int ImageBuf.{\ce xend} \\ 1540int ImageBuf.{\ce ybegin} \\ 1541int ImageBuf.{\ce yend} \\ 1542int ImageBuf.{\ce zbegin} \\ 1543int ImageBuf.{\ce zend}} 1544The range of valid pixel data window. Remember that the {\cf end} is 1545\emph{one past} the last pixel. 1546\apiend 1547 1548\apiitem{int ImageBuf.{\ce xmin} \\ 1549int ImageBuf.{\ce xmax} \\ 1550int ImageBuf.{\ce ymin} \\ 1551int ImageBuf.{\ce ymax} \\ 1552int ImageBuf.{\ce zmin} \\ 1553int ImageBuf.{\ce zmax}} 1554The minimum and maximum (inclusive) coordinates of the pixel data window. 1555\apiend 1556 1557\apiitem{int ImageBuf.{\ce orientation} \\ 1558int ImageBuf.{\ce oriented_width} \\ 1559int ImageBuf.{\ce oriented_height} \\ 1560int ImageBuf.{\ce oriented_x} \\ 1561int ImageBuf.{\ce oriented_y} \\ 1562int ImageBuf.{\ce oriented_full_width} \\ 1563int ImageBuf.{\ce oriented_full_height} \\ 1564int ImageBuf.{\ce oriented_full_x} \\ 1565int ImageBuf.{\ce oriented_full_y}} 1566The {\cf orientation} field gives the suggested display oriententation of 1567the image (see Section~\ref{metadata:orientation}). 1568 1569The other fields are helpers that give the width, height, and origin 1570(as well as ``full'' or ``display'' resolution and origin), taking the 1571intended orientation into consideration. 1572\apiend 1573 1574\apiitem{ROI ImageBuf.{\ce roi} \\ 1575ROI ImageBuf.{\ce roi_full}} 1576These fields return an \ROI description of the pixel data window 1577({\cf roi}) and the full (a.k.a.\ ``display'') window ({\cf roi_full}). 1578 1579\noindent Example: 1580\begin{code} 1581 buf = ImageBuf ("tahoe.jpg") 1582 print "Resolution is", buf.roi.width, "x", buf.roi.height 1583\end{code} 1584\apiend 1585 1586\apiitem{ImageBuf.{\ce set_origin} (x, y, z=0)} 1587Changes the ``origin'' of the data pixel data window to the specified 1588coordinates. 1589 1590\noindent Example: 1591\begin{code} 1592 # Shift the pixel data so the upper left is at pixel (10, 10) 1593 buf.set_origin (10, 10) 1594\end{code} 1595\apiend 1596 1597\apiitem{ImageBuf.{\ce set_full} (roi)} 1598Changes the ``full'' (a.k.a. ``display'') window to the specified ROI. 1599 1600\noindent Example: 1601\begin{code} 1602 newroi = ROI (0, 1024, 0, 768) 1603 buf.set_full (newroi) 1604\end{code} 1605\apiend 1606 1607\apiitem{bool ImageBuf.{\ce pixels_valid}} 1608Will be {\cf True} if the file has already been read and the pixels are 1609valid. (It is always {\cf True} for writable \ImageBuf's.) 1610There should be few good reasons to access these, since the spec and pixels 1611will be automatically be read when they are needed. 1612\apiend 1613 1614\apiitem{TypeDesc ImageBuf.{\ce pixeltype}} 1615Returns the description of the data type of the pixels stored within the 1616\ImageBuf. 1617\apiend 1618 1619\apiitem{ImageBuf.{\ce copy_metadata} (other_imagebuf)} 1620Replaces the metadata (all \ImageSpec items, except for the data format 1621and pixel data window size) with the corresponding metadata from the 1622other \ImageBuf. 1623\apiend 1624 1625\apiitem{ImageBuf.{\ce copy_pixels} (other_imagebuf)} 1626Replace the pixels in this \ImageBuf with the values from the other 1627\ImageBuf. 1628\apiend 1629 1630\apiitem{ImageBuf ImageBuf.{\ce copy} (format=TypeUnknown)} 1631Return a full copy of this \ImageBuf (with optional data format conversion, 1632if {\cf format} is supplied). 1633 1634\noindent Example: 1635\begin{code} 1636 A = ImageBuf("A.tif") 1637 1638 # Make a separate, duplicate copy of A 1639 B = A.copy() 1640 1641 # Make another copy of A, but converting to float pixels 1642 C = A.copy ("float") 1643\end{code} 1644\apiend 1645 1646\apiitem{ImageBuf.{\ce copy} (other_imagebuf, format=TypeUnknown)} 1647Make this \ImageBuf a complete copy of the other \ImageBuf. 1648If a {\cf format} is provided, {\cf this} will get the specified pixel 1649data type rather than using the same pixel format as the source \ImageBuf. 1650 1651\noindent Example: 1652\begin{code} 1653 A = ImageBuf("A.tif") 1654 1655 # Make a separate, duplicate copy of A 1656 B = ImageBuf() 1657 B.copy (A) 1658 1659 # Make another copy of A, but converting to float pixels 1660 C = ImageBuf() 1661 C.copy (A, oiio.FLOAT) 1662\end{code} 1663\apiend 1664 1665\apiitem{ImageBuf.{\ce swap} (other_imagebuf)} 1666Swaps the content of this \ImageBuf and the other \ImageBuf. 1667 1668\noindent Example: 1669\begin{code} 1670 A = ImageBuf("A.tif") 1671 B = ImageBuf("B.tif") 1672 A.swap (B) 1673 # Now B contains the "A.tif" image and A contains the "B.tif" image 1674\end{code} 1675\apiend 1676 1677\apiitem{tuple ImageBuf.{\ce getpixel} (x, y, z=0, wrap="black")} 1678Retrieves pixel $(x,y,z)$ from the buffer and return it as a tuple of 1679{\cf float} values, one for each color channel. The {\cf x, y, z} values 1680are {\cf int} pixel coordinates. The optional {\cf wrap} parameter 1681describes what should happen if the coordinates are outside the pixel data 1682window (and may be: \qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}). 1683 1684\noindent Example: 1685\begin{code} 1686 buf = ImageBuf ("tahoe.jpg") 1687 p = buf.getpixel (50, 50) 1688 print p 1689 1690 > (0.37, 0.615, 0.97) 1691\end{code} 1692\apiend 1693 1694\apiitem{float ImageBuf.{\ce getchannel} (x, y, z, channel, wrap="black")} 1695Retrieves just a single channel value from pixel $(x,y,z)$ from the buffer 1696and returns it as a {\cf float} value. The optional {\cf wrap} parameter 1697describes what should happen if the coordinates are outside the pixel data 1698window (and may be: \qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}). 1699 1700\noindent Example: 1701\begin{code} 1702 buf = ImageBuf ("tahoe.jpg") 1703 green = buf.getchannel (50, 50, 0, 1) 1704\end{code} 1705\apiend 1706 1707\apiitem{tuple ImageBuf.{\ce interppixel} (x, y, wrap="black") \\ 1708tuple ImageBuf.{\ce interppixel_bicubic} (x, y, wrap="black")} 1709Interpolates the image value (bilinearly or bicubically) 1710at coordinates $(x,y)$ and return it as a tuple 1711of {\cf float} values, one for each color channel. The {\cf x, y} values 1712are continuous {\cf float} coordinates in ``pixel space.'' The optional 1713{\cf wrap} parameter describes what should happen if the coordinates are 1714outside the pixel data window (and may be: 1715\qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}). 1716 1717\noindent Example: 1718\begin{code} 1719 buf = ImageBuf ("tahoe.jpg") 1720 midx = float(buf.xbegin + buf.xend) / 2.0 1721 midy = float(buf.ybegin + buf.yend) / 2.0 1722 p = buf.interpixel (midx, midy) 1723 # Now p is the interpolated value from right in the center of 1724 # the data window 1725\end{code} 1726\apiend 1727 1728\apiitem{tuple ImageBuf.{\ce interppixel_NDC} (x, y, wrap="black") \\ 1729tuple ImageBuf.{\ce interppixel_bicubic_NDC} (x, y, wrap="black")} 1730 1731Interpolates the image value (bilinearly or bicubically) 1732at coordinates $(x,y)$ and return it as a tuple 1733of {\cf float} values, one for each color channel. The {\cf x, y} values 1734are continuous, normalized {\cf float} coordinates in ``NDC space,'' where 1735{\cf (0,0)} is the upper left corner of the full (a.k.a.\ ``display'') 1736window, and {\cf (1,1)} is the lower right corner of the full/display 1737window. The {\cf wrap} parameter describes what should happen if the 1738coordinates are outside the pixel data window (and may be: 1739\qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}). 1740 1741\noindent Example: 1742\begin{code} 1743 buf = ImageBuf ("tahoe.jpg") 1744 p = buf.interpixel_NDC (0.5, 0.5) 1745 # Now p is the interpolated value from right in the center of 1746 # the display window 1747\end{code} 1748\apiend 1749 1750\apiitem{ImageBuf.{\ce setpixel} (x, y, pixel_value) \\ 1751ImageBuf.{\ce setpixel} (x, y, z, pixel_value)} 1752Sets pixel $(x,y,z)$ to be the {\cf pixel_value}, expressed as a tuple of 1753{\cf float}s (one for each color channel). 1754 1755\noindent Example: 1756\begin{code} 1757 buf = ImageBuf (ImageSpec (640, 480, 3, oiio.UINT8)) 1758 1759 # Set the whole image to red (the dumb slow way, but it works): 1760 for y in range(buf.ybegin, buf.yend) : 1761 for x in range(buf.xbegin, buf.xend) : 1762 buf.setpixel (x, y, (1.0, 0.0, 0.0)) 1763\end{code} 1764\apiend 1765 1766\apiitem{array ImageBuf.{\ce get_pixels} (format=TypeFloat, roi=ROI.All)} 1767 1768Retrieves the rectangle of pixels (and channels) specified by {\cf roi} from 1769the image and returns them as an array of values with type specified by 1770{\cf format}. 1771 1772As with the {\cf ImageInput} read functions, the return value is a NumPy 1773{\cf ndarray} containing data elements indexed as 1774{\cf [y][x][channel]} for normal 2D images, or for 3D volumetric images, 1775as {\cf [z][y][x][channel]}). 1776Returns {\cf True} upon success, {\cf False} upon failure. 1777 1778\noindent Example: 1779\begin{code} 1780 buf = ImageBuf ("tahoe.jpg") 1781 pixels = buf.get_pixels (oiio.FLOAT) # no ROI means the whole image 1782\end{code} 1783\apiend 1784 1785\apiitem{ImageBuf.{\ce set_pixels} (roi, data)} 1786 1787Sets the rectangle of pixels (and channels) specified by {\cf roi} with 1788values in the {\cf data}, which is a NumPy {\cf ndarray} of values 1789indexed as {\cf [y][x][channel]} for normal 2D images, or for 3D volumetric images, 1790as {\cf [z][y][x][channel]}. (It will also work fine if 1791the array is 1D ``flattened'' version, as long as it contains the correct 1792total number of values.) The data type is deduced from the contents of the 1793array itself. 1794 1795\noindent Example: 1796\begin{code} 1797 buf = ImageBuf (...) 1798 pixels = (....) 1799 buf.set_pixels (ROI(), pixels) 1800\end{code} 1801\apiend 1802 1803\apiitem{bool ImageBuf.{\ce has_error} \\ 1804str ImageBuf.{\ce geterror} ()} 1805The {\cf ImageBuf.has_error} field will be {\cf True} if an error has 1806occurred in the \ImageBuf, in which case the {\cf geterror()} method will 1807retrieve the error message (and clear it afterwards). 1808 1809\noindent Example: 1810\begin{code} 1811 buf = ImageBuf ("in.tif") 1812 buf.read () # force a read 1813 if buf.has_error : 1814 print "Error reading the file:", buf.geterror() 1815 buf.write ("out.jpg") 1816 if buf.has_error : 1817 print "Could not convert the file:", buf.geterror() 1818\end{code} 1819\apiend 1820 1821\apiitem{int ImageBuf.{\ce pixelindex} (x, y, z, check_range=False)} 1822Return the index of pixel (x,y,z). 1823\apiend 1824 1825\apiitem{bool ImageBuf.{\ce deep}} 1826Will be {\cf True} if the file contains ``deep'' pixel data, or {\cf False} 1827for an ordinary images. 1828\apiend 1829 1830\apiitem{int ImageBuf.{\ce deep_samples} (x, y, z=0)} 1831Return the number of deep samples for pixel (x,y,z). 1832\apiend 1833 1834\apiitem{ImageBuf.{\ce set_deep_samples} (x, y, z, nsamples)} 1835Set the number of deep samples for pixel (x,y,z). 1836\apiend 1837 1838\apiitem{ImageBuf.{\ce deep_insert_samples} (x, y, z, samplepos, nsamples) \\ 1839int ImageBuf.{\ce deep_erase_samples} (x, y, z, samplepos, nsamples)} 1840Insert or erase \emph{nsamples} samples starting at the given position of 1841pixel {\cf (x,y,z)}. 1842\apiend 1843 1844\apiitem{float ImageBuf.{\ce deep_value} (x, y, z, channel, sample) \\ 1845uint ImageBuf.{\ce deep_value_uint} (x, y, z, channel, sample)} 1846Return the value of the given deep sample (particular pixel, channel, and 1847sample number) for a channel that is a float or an unsigned integer type, 1848respectively. 1849\apiend 1850 1851\apiitem{ImageBuf.{\ce set_deep_value} (x, y, z, channel, sample, value) \\ 1852ImageBuf.{\ce set_deep_value_uint} (x, y, z, channel, sample, value)} 1853Set the value of the given deep sample (particular pixel, channel, and 1854sample number) for a channel that is a float or an unsigned integer type, 1855respectively. 1856\apiend 1857 1858\apiitem{DeepData ImageBuf.{\ce deepdata}} 1859Returns a reference to the underlying {\cf DeepData} of the image. 1860\apiend 1861 1862 1863 1864 1865\newpage 1866\section{ImageBufAlgo} 1867\label{sec:pythonimagebufalgo} 1868 1869The C++ \IBA functions are described in detail in 1870Chapter~\ref{chap:imagebufalgo}. They are also exposed to Python. 1871For the majority of \IBA functions, their use in Python is identical 1872to C++; in those cases, we will keep our descriptions of the Python 1873bindings minimal and refer you to Chapter~\ref{chap:imagebufalgo}, saving 1874the extended descriptions for those functions that differ from the C++ 1875counterparts. 1876 1877A few things about the paramters of the \IBA function calls are identical 1878among the functions, so we will explain once here rather than separately for 1879each function: 1880 1881\begin{itemize} 1882\item {\cf dst} is an existing \ImageBuf, which will be modified (it may be 1883an uninitialized \ImageBuf, but it must be an \ImageBuf). 1884\item {\cf src} parameter is an initialized \ImageBuf, which will not be 1885modified (unless it happens to refer to the same image as {\cf dst}. 1886\item {\cf roi}, if supplied, is an {\cf ROI} specifying a region of interst 1887over which to operate. If omitted, the region will be the entire size of the 1888source image(s). 1889\item {\cf nthreads} is the maximum number of threads to use. If not 1890supplied, it defaults to 0, meaning to use as many threads as hardware cores 1891available. 1892\end{itemize} 1893 1894Just as with the C++ \IBA functions, if {\cf dst} is an uninitialized 1895\ImageBuf, it will be sized to reflect the {\cf roi} (which, in turn, if 1896undefined, will be sized to be the union of the ROI's of the source 1897images). 1898 1899\subsection{Pattern generation} 1900\label{sec:iba:py:patterns} 1901 1902\apiitem{ImageBuf ImageBufAlgo.{\ce zero} (roi, nthreads=0) \\ 1903bool ImageBufAlgo.{\ce zero} (dst, roi=ROI.All, nthreads=0)} 1904\index{ImageBufAlgo!zero} \indexapi{zero} 1905 1906Zero out the destination buffer (or a specific region of it). 1907 1908\smallskip 1909\noindent Example: 1910\begin{code} 1911 # Initialize buf to a 640x480 3-channel FLOAT buffer of 0 values 1912 buf = ImageBufAlgo.zero (ROI(0, 640, 0, 480, 0, 1, 0, 3)) 1913\end{code} 1914\apiend 1915 1916\apiitem{ImageBuf ImageBufAlgo.{\ce fill} (values, roi=ROI.All, nthreads=0) \\ 1917ImageBuf ImageBufAlgo.{\ce fill} (top, bottom, roi=ROI.All, nthreads=0) \\ 1918ImageBuf ImageBufAlgo.{\ce fill} (topleft, topright, \\ 1919\bigspc bottomleft, bottomright, roi=ROI.All, nthreads=0) \\[0.5ex] 1920bool ImageBufAlgo.{\ce fill} (dst, values, roi=ROI.All, nthreads=0) \\ 1921bool ImageBufAlgo.{\ce fill} (dst, top, bottom, roi=ROI.All, nthreads=0) \\ 1922bool ImageBufAlgo.{\ce fill} (dst, topleft, topright, \\ 1923\bigspc bottomleft, bottomright, roi=ROI.All, nthreads=0)} 1924\index{ImageBufAlgo!fill} \indexapi{fill} 1925 1926Return a filled float image of size ROI, or set the the pixels of image 1927{\cf dst} within the ROI to a color or gradient. 1928 1929Three fill optins are available: (a) if one color tuple is supplied, the 1930whole ROI will be filled with that constant value, (b) if two color tuples 1931are supplied, a linear gradient will be applied from top to bottom, (c) if 1932four color cuples are supplied, the ROI will be be filled with values 1933bilinearly interpolated from the four corner colors supplied. 1934 1935\smallskip 1936\noindent Examples: 1937\begin{code} 1938 # Draw a red rectangle into buf 1939 buf = ImageBuf (ImageSpec(640, 480, 3, TypeDesc.FLOAT) 1940 ImageBufAlgo.fill (buf, (1,0,0), ROI(50, 100, 75, 85)) 1941\end{code} 1942\apiend 1943 1944 1945\apiitem{ImageBuf ImageBufAlgo.{\ce checker} (width, height, depth, 1946 color1, color2, \\ \bigspc xoffset=0, yoffset=0, zoffset=0, 1947 roi=ROI.All, nthreads=0) \\ 1948 bool ImageBufAlgo.{\ce checker} (dst, width, height, depth, 1949 color1, color2, \\ \bigspc xoffset=0, yoffset=0, zoffset=0, 1950 roi=ROI.All, nthreads=0)} 1951\index{ImageBufAlgo!checker} \indexapi{checker} 1952 1953Return (or copy into {\cf dst}) a checkerboard pattern. The colors are specified as 1954tuples giving the values for each color channel. 1955 1956\smallskip 1957\noindent Examples: 1958\begin{code} 1959 buf = ImageBuf(ImageSpec(640, 480, 3, oiio.UINT8)) 1960 ImageBufAlgo.checker (buf, 64, 64, 1, (0.1,0.1,0.1), (0.4,0.4,0.4)) 1961\end{code} 1962\apiend 1963 1964 1965\apiitem{ImageBuf ImageBufAlgo.{\ce noise} (noisetype, A=0.0, B=0.1, \\ 1966\bigspc\bigspc mono=False, seed=0, roi=ROI.All, nthreads=0)\\ 1967bool ImageBufAlgo.{\ce noise} (dst, noisetype, A=0.0, B=0.1,\\ 1968\bigspc\bigspc mono=False, seed=0, roi=ROI.All, nthreads=0)} 1969\index{ImageBufAlgo!noise} \indexapi{noise} 1970 1971Return an image of pseudorandom noise, or add pseudorandom noise 1972to the specified region of existing region {\cf dst}. 1973 1974For noise type \qkw{uniform}, the noise is uniformly distributed on the 1975range {\cf [A,B)}. For noise \qkw{gaussian}, the noise will have a normal 1976distribution with mean A and standard deviation B. For noise \qkw{salt}, the 1977value A will be stored in a random set of pixels whose proportion (of the 1978overall image) is B. For all noise types, choosing different {\cf seed} 1979values will result in a different pattern. If the {\cf mono} flag is {\cf 1980true}, a single noise value will be applied to all channels specified by 1981{\cf roi}, but if {\cf mono} is {\cf false}, a separate noise value will be 1982computed for each channel in the region. 1983 1984\smallskip 1985\noindent Examples: 1986\begin{code} 1987 buf = ImageBuf(ImageSpec(640, 480, 3, oiio.UINT8)) 1988 ImageBufAlgo.zero (buf) 1989 ImageBufAlgo.noise (buf, 'uniform', 0.25, 0.75) 1990\end{code} 1991\apiend 1992 1993 1994 1995\apiitem{bool ImageBufAlgo.{\ce render_point} (dst, x, y, color=(1,1,1,1))} 1996\index{ImageBufAlgo!render_point} \indexapi{render_point} 1997 1998Render a point at pixel $(x,y)$ of {\cf dst}. The {\cf color} (if supplied) 1999is a tuple giving the per-channel colors. 2000 2001\smallskip 2002\noindent Examples: 2003\begin{code} 2004 buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT)) 2005 ImageBufAlgo.render_point (buf, 10, 20, (1,0,0,1)) 2006\end{code} 2007\apiend 2008 2009 2010\apiitem{bool ImageBufAlgo.{\ce render_line} (dst, x1, y1, x2, y2, \\ 2011\bigspc\bigspc color=(1,1,1,1), skip_first_point=False)} 2012\index{ImageBufAlgo!render_line} \indexapi{render_line} 2013 2014Render a line from pixel $(x_1,y_1)$ to $(x_2,y_2)$ into {\cf dst}. The 2015{\cf color} (if supplied) is a tuple giving the per-channel colors. 2016 2017\smallskip 2018\noindent Examples: 2019\begin{code} 2020 buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT)) 2021 ImageBufAlgo.render_line (buf, 10, 10, 500, 20, (1,0,0,1)) 2022\end{code} 2023\apiend 2024 2025 2026\apiitem{bool ImageBufAlgo.{\ce render_box} (dst, x1, y1, x2, y2, \\ 2027\bigspc\bigspc color=(1,1,1,1), filled=False)} 2028\index{ImageBufAlgo!render_box} \indexapi{render_box} 2029 2030Render a filled or unfilled box with corners at pixels $(x_1,y_1)$ and 2031$(x_2,y_2)$ into {\cf dst}. The {\cf color} (if supplied) is a tuple giving 2032the per-channel colors. 2033 2034\smallskip 2035\noindent Examples: 2036\begin{code} 2037 buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT)) 2038 ImageBufAlgo.render_box (buf, 150, 100, 240, 180, (0,1,1,1)) 2039 ImageBufAlgo.render_box (buf, 100, 50, 180, 140, (0.5, 0.5, 0, 0.5), True) 2040\end{code} 2041\apiend 2042 2043 2044\apiitem{bool ImageBufAlgo.{\ce render_text} (dst, x, y, text, fontsize=16, \\ 2045 \bigspc\bigspc fontname="", textcolor=(1,1,1,1),\\ 2046 \bigspc\bigspc alignx="left", aligny="baseline", shadow=0,\\ 2047 \bigspc\bigspc roi=ROI.All, nthreads=0} 2048\index{ImageBufAlgo!render_text} \indexapi{render_text} 2049 2050Render antialiased text into {\cf dst}. The {\cf textcolor} (if supplied) 2051is a tuple giving the per-channel colors. Choices for {\cf alignx} are 2052\qkw{left}, \qkw{right}, and \qkw{center}, and choices for {\cf aligny} are 2053\qkw{baseline}, \qkw{top}, \qkw{bottom}, and \qkw{center}. 2054 2055\smallskip 2056\noindent Examples: 2057\begin{code} 2058 buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT)) 2059 ImageBufAlgo.render_text (buf, 50, 100, "Hello, world") 2060 ImageBufAlgo.render_text (buf, 100, 200, "Go Big Red!", 2061 60, "Arial Bold", (1,0,0,1)) 2062\end{code} 2063% \spc \includegraphics[width=2.5in]{figures/text.jpg} 2064\apiend 2065 2066 2067\apiitem{ROI ImageBufAlgo.{\ce text_size} (text, fontsize=16, fontname="")} 2068\index{ImageBufAlgo!text_size} \indexapi{text_size} 2069 2070Compute the size that will be needed for the text as an ROI and return it. 2071The size will not be {\cf defined} if an error occurred (such as not being a 2072valid font name). 2073 2074\smallskip 2075\noindent Examples: 2076\begin{code} 2077 A = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT)) 2078 Aroi = A.roi 2079 size = ImageBufAlgo.text_size ("Centered", 40, "Courier New") 2080 if size.defined : 2081 x = Aroi.xbegin + Aroi.width/2 - (size.xbegin + size.width/2) 2082 y = Aroi.ybegin + Aroi.height/2 - (size.ybegin + size.height/2) 2083 ImageBufAlgo.render_text (A, x, y, "Centered", 40, "Courier New") 2084 2085 # Note: this was for illustration. An easier way to do this is: 2086 # render_text (A, x, y, "Centered", 40, "Courier New", alignx="center") 2087\end{code} 2088% \spc \includegraphics[width=2.5in]{figures/textcentered.jpg} 2089\apiend 2090 2091 2092 2093\subsection{Image transformations and data movement} 2094\label{sec:iba:py:transforms} 2095 2096\apiitem{ImageBuf ImageBufAlgo.{\ce channels} (src, channelorder, newchannelnames=(), \\ 2097 \bigspc\bigspc shuffle_channel_names=False, nthreads=0) \\ 2098bool ImageBufAlgo.{\ce channels} (dst, src, channelorder, newchannelnames=(), \\ 2099 \bigspc\bigspc shuffle_channel_names=False, nthreads=0)} 2100\index{ImageBufAlgo!channels} \indexapi{channels} 2101 2102Return (or store in {\cf dst}) shuffled channels of {\cf src}, with channels in 2103the order specified by the tuple {\cf channelorder}. 2104The length of {\cf channelorder} specifies the number of channels to copy. 2105Each element in the tuple {\cf channelorder} may be one of the following: 2106\begin{itemize} 2107\item {} 2108\item {\cf int} : specifies the index (beginning at 0) of the channel 2109 to copy. 2110\item {\cf str} : specifies the name of the channel to copy. 2111\item {\cf float} : specifies a constant value to use for that channel. 2112\end{itemize} 2113 2114If {\cf newchannelnames} is supplied, it is a tuple of new channel 2115names. (See the C++ version for more full explanation.) 2116 2117\smallskip 2118\noindent Examples: 2119\begin{code} 2120 # Copy the first 3 channels of an RGBA, drop the alpha 2121 RGBA = ImageBuf("rgba.tif") 2122 RGB = ImageBufAlgo.channels (RGBA, (0,1,2)) 2123 2124 # Copy just the alpha channel, making a 1-channel image 2125 Alpha = ImageBufAlgo.channels (RGBA, ("A",)) 2126 2127 # Swap the R and B channels 2128 BGRA = ImageBufAlgo.channels (RGBA, (2, 1, 0, 3)) 2129 2130 # Add an alpha channel with value 1.0 everywhere to an RGB image 2131 RGBA = ImageBufAlgo.channels (RGB, ("R", "G", "B", 1.0), 2132 ("R", "G", "B", "A")) 2133\end{code} 2134\apiend 2135 2136 2137\apiitem{ImageBuf ImageBufAlgo.{\ce channel_append} (A, B, roi=ROI.All, nthreads=0)\\ 2138bool ImageBufAlgo.{\ce channel_append} (dst, A, B, roi=ROI.All, nthreads=0)} 2139\index{ImageBufAlgo!channel_append} \indexapi{channel_append} 2140Append the channels of images {\cf A} and {\cf B} together into one image. 2141 2142\smallskip 2143\noindent Examples: 2144\begin{code} 2145 RGBA = ImageBuf ("rgba.exr") 2146 Z = ImageBuf ("z.exr") 2147 RGBAZ = ImageBufAlgo.channel_append (RGBA, Z) 2148\end{code} 2149\apiend 2150 2151 2152\apiitem{ImageBuf ImageBufAlgo.{\ce copy} (src, convert=TypeDesc.UNKNOWN, \\ 2153 \bigspc roi=ROI.All, nthreads=0)\\ 2154bool ImageBufAlgo.{\ce copy} (dst, src, convert=TypeDesc.UNKNOWN, \\ 2155 \bigspc roi=ROI.All, nthreads=0)} 2156\index{ImageBufAlgo!copy} \indexapi{copy} 2157Copy the specified region of pixels of {\cf src} at the same 2158locations, optionally with the pixel 2159type overridden by {\cf convert} (if it is not {\cf UNKNOWN}). 2160 2161\smallskip 2162\noindent Examples: 2163\begin{code} 2164 # Copy A's upper left 200x100 region into B 2165 B = ImageBufAlgo.copy (A, ROI(0,200,0,100)) 2166\end{code} 2167\apiend 2168 2169 2170\apiitem{ImageBuf ImageBufAlgo.{\ce crop} (src, roi=ROI.All, nthreads=0)\\ 2171bool ImageBufAlgo.{\ce crop} (dst, src, roi=ROI.All, nthreads=0)} 2172\index{ImageBufAlgo!crop} \indexapi{crop} 2173Reset {\cf dst} to be the specified region of {\cf src}. 2174 2175\smallskip 2176\noindent Examples: 2177\begin{code} 2178 # Set B to be the upper left 200x100 region of A 2179 A = ImageBuf ("a.tif") 2180 B = ImageBufAlgo.crop (A, ROI(0,200,0,100)) 2181\end{code} 2182\apiend 2183 2184 2185\apiitem{ImageBuf ImageBufAlgo.{\ce cut} (src, roi=ROI.All, nthreads=0)\\ 2186bool ImageBufAlgo.{\ce cut} (dst, src, roi=ROI.All, nthreads=0)} 2187\index{ImageBufAlgo!cut} \indexapi{cut} 2188Reset {\cf dst} to be the specified region of {\cf src}, but moved so 2189that the resulting new image has its pixel data at the image plane origin. 2190 2191\smallskip 2192\noindent Examples: 2193\begin{code} 2194 # Set B to be the lower left 200x100 region of A, moved to the origin 2195 A = ImageBuf ("a.tif") 2196 B = ImageBufAlgo.cut (A, ROI(0,200,380,480)) 2197\end{code} 2198\apiend 2199 2200 2201\apiitem{bool ImageBufAlgo.{\ce paste} (dst, xbegin, ybegin, zbegin, chbegin, \\ 2202 \bigspc\bigspc src, ROI srcroi=ROI.All, nthreads=0)} 2203\index{ImageBufAlgo!paste} \indexapi{paste} 2204Copy the specified region of {\cf src} into {\cf dst} beginning at 2205offset {\cf (xbegin, ybegin, zbegin)}. 2206 2207\smallskip 2208\noindent Examples: 2209\begin{code} 2210 # Paste small.exr on top of big.exr at offset (100,100) 2211 Big = ImageBuf ("big.exr") 2212 Small = ImageBuf ("small.exr") 2213 ImageBufAlgo.paste (Big, 100, 100, 0, 0, Small) 2214\end{code} 2215\apiend 2216 2217 2218\apiitem{ImageBuf ImageBufAlgo.{\ce rotate90} (src, roi=ROI.All, nthreads=0) \\ 2219ImageBuf ImageBufAlgo.{\ce rotate180} (src, roi=ROI.All, nthreads=0) \\ 2220ImageBuf ImageBufAlgo.{\ce rotate270} (src, roi=ROI.All, nthreads=0) \\[1.0ex] 2221bool ImageBufAlgo.{\ce rotate90} (dst, src, roi=ROI.All, nthreads=0) \\ 2222bool ImageBufAlgo.{\ce rotate180} (dst, src, roi=ROI.All, nthreads=0) \\ 2223bool ImageBufAlgo.{\ce rotate270} (dst, src, roi=ROI.All, nthreads=0)} 2224\index{ImageBufAlgo!roate90} \indexapi{roate90} 2225\index{ImageBufAlgo!rotate180} \indexapi{rotate180} 2226\index{ImageBufAlgo!rotate270} \indexapi{rotate270} 2227Copy while rotating the image by a multiple of 90 degrees. 2228 2229\smallskip 2230\noindent Examples: 2231\begin{code} 2232 A = ImageBuf ("tahoe.exr") 2233 B = ImageBufAlgo.rotate90 (A) 2234\end{code} 2235\apiend 2236 2237 2238 2239\apiitem{ImageBuf ImageBufAlgo.{\ce flip} (src, roi=ROI.All, nthreads=0) \\ 2240ImageBuf ImageBufAlgo.{\ce flop} (src, roi=ROI.All, nthreads=0) \\ 2241ImageBuf ImageBufAlgo.{\ce transpose} (src, roi=ROI.All, nthreads=0) \\[1.0ex] 2242bool ImageBufAlgo.{\ce flip} (dst, src, roi=ROI.All, nthreads=0) \\ 2243bool ImageBufAlgo.{\ce flop} (dst, src, roi=ROI.All, nthreads=0) \\ 2244bool ImageBufAlgo.{\ce transpose} (dst, src, roi=ROI.All, nthreads=0)} 2245\index{ImageBufAlgo!flip} \indexapi{flip} 2246\index{ImageBufAlgo!flop} \indexapi{flop} 2247\index{ImageBufAlgo!transpose} \indexapi{transpose} 2248Copy while reversing orientation vertically (flip) or horizontally (flop), 2249or diagonally (transpose). 2250 2251\smallskip 2252\noindent Examples: 2253\begin{code} 2254 A = ImageBuf ("tahoe.exr") 2255 B = ImageBufAlgo.flip (A) 2256\end{code} 2257\apiend 2258 2259 2260\apiitem{ImageBuf ImageBufAlgo.{\ce reorient} (src, nthreads=0) \\ 2261bool ImageBufAlgo.{\ce reorient} (dst, src, nthreads=0)} 2262\index{ImageBufAlgo!reorient} \indexapi{reorient} 2263 2264Copy {\cf src}, applying whatever seties of rotations, flips, 2265or flops are necessary to transform the pixels into the configuration 2266suggested by the \qkw{Orientation} metadata of the image (and the 2267\qkw{Orientation} metadata is then set to 1, ordinary orientation). 2268 2269\smallskip 2270\noindent Examples: 2271\begin{code} 2272 A = ImageBuf ("tahoe.jpg") 2273 ImageBufAlgo.reorient (A, A) 2274\end{code} 2275\apiend 2276 2277 2278 2279\apiitem{ImageBuf ImageBufAlgo.{\ce circular_shift} (src, xshift, yshift, zshift=0, \\ 2280 \bigspc roi=ROI.All, nthreads=0)\\ 2281bool ImageBufAlgo.{\ce circular_shift} (dst, src, xshift, yshift, zshift=0, \\ 2282 \bigspc roi=ROI.All, nthreads=0)} 2283\index{ImageBufAlgo!circular_shift} \indexapi{circular_shift} 2284 2285Copy while circularly shifting by the given amount. 2286 2287\smallskip 2288\noindent Examples: 2289\begin{code} 2290 A = ImageBuf ("tahoe.exr") 2291 B = ImageBufAlgo.circular_shift (A, 200, 100) 2292\end{code} 2293\apiend 2294 2295 2296\apiitem{ImageBuf ImageBufAlgo.{\ce rotate} (src, angle, filtername="", filtersize=0.0, \\ 2297 \bigspc\bigspc recompute_roi=False, roi=ROI.All, nthreads=0) \\ 2298ImageBuf ImageBufAlgo.{\ce rotate} (src, angle, \\ 2299 \bigspc\bigspc center_x, center_y, filtername="", filtersize=0.0, \\ 2300 \bigspc\bigspc recompute_roi=False, roi=ROI.All, nthreads=0) \\[1.0ex] 2301bool ImageBufAlgo.{\ce rotate} (dst, src, angle, filtername="", filtersize=0.0, \\ 2302 \bigspc\bigspc recompute_roi=False, roi=ROI.All, nthreads=0) \\ 2303bool ImageBufAlgo.{\ce rotate} (dst, src, angle, \\ 2304 \bigspc\bigspc center_x, center_y, filtername="", filtersize=0.0, \\ 2305 \bigspc\bigspc recompute_roi=False, roi=ROI.All, nthreads=0) } 2306\index{ImageBufAlgo!rotate} \indexapi{rotate} 2307 2308Copy arotated version of the 2309corresponding portion of {\cf src}. The angle is in radians, with positive 2310values indicating clockwise rotation. If the filter and size are not 2311specified, an appropriate default will be chosen. 2312 2313\smallskip 2314\noindent Examples: 2315\begin{code} 2316 Src = ImageBuf ("tahoe.exr") 2317 Dst = ImageBufAlgo.rotate (Src, math.radians(45.0)) 2318\end{code} 2319\apiend 2320 2321 2322\apiitem{ImageBuf ImageBufAlgo.{\ce warp} (src, M, filtername="", filtersize=0.0, \\ 2323 \bigspc\bigspc wrap="default", recompute_roi=False, \\ 2324 \bigspc\bigspc roi=ROI.All, nthreads=0)\\ 2325bool ImageBufAlgo.{\ce warp} (dst, src, M, filtername="", filtersize=0.0, \\ 2326 \bigspc\bigspc wrap="default", recompute_roi=False, \\ 2327 \bigspc\bigspc roi=ROI.All, nthreads=0)} 2328\index{ImageBufAlgo!warp} \indexapi{warp} 2329 2330Compute a warped (transformed) copy of {\cf src}, 2331with the warp specified by {\cf M} consisting of 9 floating-point numbers 2332representing a $3 \times 3$ transformation matrix. If the filter and size 2333are not specified, an appropriate default will be chosen. 2334 2335\smallskip 2336\noindent Examples: 2337\begin{code} 2338 M = (0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 20, -8.284271, 1) 2339 Src = ImageBuf ("tahoe.exr") 2340 Dst = ImageBufAlgo.warp (Src, M) 2341\end{code} 2342\apiend 2343 2344 2345\apiitem{ImageBuf ImageBufAlgo.{\ce resize} (src, filtername="", filtersize=0.0, \\ 2346 \bigspc\bigspc roi=ROI.All, nthreads=0) \\ 2347bool ImageBufAlgo.{\ce resize} (dst, src, filtername="", filtersize=0.0, \\ 2348 \bigspc\bigspc roi=ROI.All, nthreads=0)} 2349\index{ImageBufAlgo!resize} \indexapi{resize} 2350Compute a high-quality resized version of the 2351corresponding portion of {\cf src}. If the filter and size are not 2352specified, an appropriate default will be chosen. 2353 2354\smallskip 2355\noindent Examples: 2356\begin{code} 2357 # Resize the image to 640x480, using the default filter 2358 Src = ImageBuf ("tahoe.exr") 2359 Dst = ImageBufAlgo.resize (Src, roi=ROI(0,640,0,480,0,1,0,3)) 2360\end{code} 2361\apiend 2362 2363 2364\apiitem{ImageBuf ImageBufAlgo.{\ce resample} (src, interpolate=True, \\ 2365 \bigspc\bigspc roi=ROI.All, nthreads=0)\\ 2366bool ImageBufAlgo.{\ce resample} (dst, src, interpolate=True, \\ 2367 \bigspc\bigspc roi=ROI.All, nthreads=0)} 2368\index{ImageBufAlgo!resample} \indexapi{resample} 2369Set {\cf dst}, over the ROI, to be a low-quality (but fast) resized version 2370of the corresponding portion of {\cf src}, either using a simple ``closest 2371pixel'' choice or by bilinaerly interpolating (depending on {\cf 2372interpolate}). 2373 2374\smallskip 2375\noindent Examples: 2376\begin{code} 2377 # Resample quickly to 320x240 to make a low-quality thumbnail 2378 Src = ImageBuf ("tahoe.exr") 2379 Dst = ImageBufAlgo.resample (Src, roi=ROI(0,640,0,480,0,1,0,3)) 2380\end{code} 2381\apiend 2382 2383 2384\apiitem{ImageBuf ImageBufAlgo.{\ce fit} (src, filtername="", filtersize=0.0, \\ 2385 \bigspc\bigspc exact=false, roi=ROI.All, nthreads=0) \\ 2386bool ImageBufAlgo.{\ce fit} (dst, src, filtername="", filtersize=0.0, \\ 2387 \bigspc\bigspc exact=false, roi=ROI.All, nthreads=0)} 2388\index{ImageBufAlgo!fit} \indexapi{fit} 2389Fit {\cf src} into the {\cf roi} while preserving the 2390original aspect ratio, without stretching. If the filter and size are not 2391specified, an appropriate default will be chosen. 2392 2393\smallskip 2394\noindent Examples: 2395\begin{code} 2396 # Resize to fit into a max of 640x480, preserving the aspect ratio 2397 Src = ImageBuf ("tahoe.exr") 2398 Dst = ImageBufAlgo.fit (Src, roi=ROI(0,640,0,480,0,1,0,3)) 2399\end{code} 2400\apiend 2401 2402 2403 2404\subsection{Image arithmetic} 2405\label{sec:iba:py:arith} 2406 2407\apiitem{ImageBuf ImageBufAlgo.{\ce add} (A, B, roi=ROI.All, nthreads=0)\\ 2408bool ImageBufAlgo.{\ce add} (dst, A, B, roi=ROI.All, nthreads=0)} 2409\index{ImageBufAlgo!add} \indexapi{add} 2410 2411Compute {\cf A + B}. {\cf A} and {\cf B} each may 2412be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a 2413{\cf float} for each color channel. 2414 2415\smallskip 2416\noindent Examples: 2417\begin{code} 2418 # Add two images 2419 buf = ImageBufAlgo.add (ImageBuf("a.exr"), ImageBuf("b.exr")) 2420 2421 # Add 0.2 to channels 0-2 2422 ImageBufAlgo.add (buf, buf, (0.2,0.2,0.2,0)) 2423\end{code} 2424\apiend 2425 2426 2427\apiitem{ImageBuf ImageBufAlgo.{\ce sub} (A, B, roi=ROI.All, nthreads=0)\\ 2428bool ImageBufAlgo.{\ce sub} (dst, A, B, roi=ROI.All, nthreads=0)} 2429\index{ImageBufAlgo!sub} \indexapi{sub} 2430 2431Compute {\cf A - B}. {\cf A} and {\cf B} each may 2432be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a 2433{\cf float} for each color channel. 2434 2435\smallskip 2436\noindent Examples: 2437\begin{code} 2438 buf = ImageBufAlgo.sub (ImageBuf("a.exr"), ImageBuf("b.exr")) 2439\end{code} 2440\apiend 2441 2442 2443\apiitem{ImageBuf ImageBufAlgo.{\ce absdiff} (A, B, roi=ROI.All, nthreads=0)\\ 2444bool ImageBufAlgo.{\ce absdiff} (dst, A, B, roi=ROI.All, nthreads=0)} 2445\index{ImageBufAlgo!absdiff} \indexapi{absdiff} 2446 2447Compute {\cf abs(A - B)}. {\cf A} and {\cf B} each may 2448be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a 2449{\cf float} for each color channel. 2450 2451\smallskip 2452\noindent Examples: 2453\begin{code} 2454 buf = ImageBufAlgo.absdiff (ImageBuf("a.exr"), ImageBuf("b.exr")) 2455\end{code} 2456\apiend 2457 2458 2459\apiitem{ImageBuf ImageBufAlgo.{\ce abs} (A, roi=ROI.All, nthreads=0)\\ 2460bool ImageBufAlgo.{\ce abs} (dst, A, roi=ROI.All, nthreads=0)} 2461\index{ImageBufAlgo!abs} \indexapi{abs} 2462 2463Compute {\cf abs(A)}. {\cf A} is an \ImageBuf. 2464 2465\smallskip 2466\noindent Examples: 2467\begin{code} 2468 buf = ImageBufAlgo.abs (ImageBuf("a.exr")) 2469\end{code} 2470\apiend 2471 2472 2473\apiitem{ImageBuf ImageBufAlgo.{\ce mul} (A, B, roi=ROI.All, nthreads=0)\\ 2474bool ImageBufAlgo.{\ce mul} (dst, A, B, roi=ROI.All, nthreads=0)} 2475\index{ImageBufAlgo!mul} \indexapi{mul} 2476 2477Compute {\cf A * B} (channel-by-channel multiplication). {\cf A} and {\cf B} 2478each may be an \ImageBuf, a {\cf float} value (for all channels) or a tuple 2479giving a {\cf float} for each color channel. 2480 2481\smallskip 2482\noindent Examples: 2483\begin{code} 2484 # Multiply the two images 2485 buf = ImageBufAlgo.mul (ImageBuf("a.exr"), ImageBuf("b.exr")) 2486 2487 # Reduce intensity of buf's channels 0-2 by 50%, in place 2488 ImageBufAlgo.mul (buf, buf, (0.5, 0.5, 0.5, 1.0)) 2489\end{code} 2490\apiend 2491 2492 2493\apiitem{ImageBuf ImageBufAlgo.{\ce div} (A, B, roi=ROI.All, nthreads=0)\\ 2494bool ImageBufAlgo.{\ce div} (dst, A, B, roi=ROI.All, nthreads=0)} 2495\index{ImageBufAlgo!div} \indexapi{div} 2496 2497Compute {\cf A / B} (channel-by-channel division), where $x/0$ 2498is defined to be $0$. {\cf A} and {\cf B} each may 2499be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a 2500{\cf float} for each color channel. 2501 2502\smallskip 2503\noindent Examples: 2504\begin{code} 2505 # Divide a.exr by b.exr 2506 buf = ImageBufAlgo.div (ImageBuf("a.exr"), ImageBuf("b.exr")) 2507 2508 # Reduce intensity of buf's channels 0-2 by 50%, in place 2509 ImageBufAlgo.div (buf, buf, (2.0, 2.0, 2.0, 1.0)) 2510\end{code} 2511\apiend 2512 2513 2514\apiitem{ImageBuf ImageBufAlgo.{\ce mad} (A, B, C, roi=ROI.All, nthreads=0)\\ 2515bool ImageBufAlgo.{\ce mad} (dst, A, B, C, roi=ROI.All, nthreads=0)} 2516\index{ImageBufAlgo!mad} \indexapi{mad} 2517 2518Compute {\cf A * B + C} (channel-by-channel multiplication 2519and addition). {\cf A}, {\cf B}, and {\cf C} each may 2520be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a 2521{\cf float} for each color channel. 2522 2523\smallskip 2524\noindent Examples: 2525\begin{code} 2526 # Multiply a and b, then add c 2527 buf = ImageBufAlgo.mad (ImageBuf("a.exr"), 2528 (1.0f, 0.5f, 0.25f), ImageBuf("c.exr")) 2529\end{code} 2530\apiend 2531 2532 2533 2534\apiitem{ImageBuf ImageBufAlgo.{\ce invert} (A, roi=ROI.All, nthreads=0)\\ 2535bool ImageBufAlgo.{\ce invert} (dst, A, roi=ROI.All, nthreads=0)} 2536\index{ImageBufAlgo!invert} \indexapi{invert} 2537 2538Compute {\cf 1-A} (channel by channel color inverse). 2539{\cf A} is an \ImageBuf. 2540 2541\smallskip 2542\noindent Examples: 2543\begin{code} 2544 buf = ImageBufAlgo.invert (ImageBuf("a.exr")) 2545\end{code} 2546\apiend 2547 2548 2549\apiitem{ImageBuf ImageBufAlgo.{\ce pow} (A, B, roi=ROI.All, nthreads=0)\\ 2550bool ImageBufAlgo.{\ce pow} (dst, A, B, roi=ROI.All, nthreads=0)} 2551\index{ImageBufAlgo!pow} \indexapi{pow} 2552 2553Compute {\cf pow (A, B} (channel-by-channel exponentiation). 2554{\cf A} is an \ImageBuf, and {\cf B} may be a {\cf float} (a single power 2555for all channels) or a tuple giving a {\cf float} for each color channel. 2556 2557\smallskip 2558\noindent Examples: 2559\begin{code} 2560 # Linearize a 2.2 gamma-corrected image (channels 0-2 only) 2561 img = ImageBuf ("a.exr") 2562 buf = ImageBufAlgo.pow (img, (2.2, 2.2, 2.2, 1.0)) 2563\end{code} 2564\apiend 2565 2566 2567\apiitem{ImageBuf ImageBufAlgo.{\ce channel_sum} (src, weights=(), roi=ROI.All, nthreads=0)\\ 2568bool ImageBufAlgo.{\ce channel_sum} (dst, src, weights=(), roi=ROI.All, nthreads=0)} 2569\index{ImageBufAlgo!channel_sum} \indexapi{channel_sum} 2570Converts a multi-channel image into a 1-channel image via a weighted sum 2571of channels. The {\cf weights} is a tuple providing the weight for each 2572channel (if not supplied, all channels will have weight 1.0). 2573 2574\smallskip 2575\noindent Examples: 2576\begin{code} 2577 # Compute luminance via a weighted sum of R,G,B 2578 # (assuming Rec709 primaries and a linear scale) 2579 ImageBuf() 2580 weights = (.2126, .7152, .0722) 2581 luma = ImageBufAlgo.channel_sum (ImageBuf("a.exr"), weights) 2582\end{code} 2583\apiend 2584 2585 2586\apiitem{ImageBuf ImageBufAlgo.{\ce contrast_remap} (src, \\ 2587 \bigspc\spc black=0.0, white=1.0, min=0.0, max=1.0, \\ 2588 \bigspc\spc sthresh=0.0, scontrast=1.0, \\ 2589 \bigspc\spc ROI roi=\{\}, int nthreads=0) \\ 2590bool ImageBufAlgo.{\ce contrast_remap} (ImageBuf \&dst, src,\\ 2591 \bigspc\spc black=0.0, white=1.0, min=0.0, max=1.0, \\ 2592 \bigspc\spc sthresh=0.0, scontrast=1.0, \\ 2593 \bigspc\spc ROI roi=\{\}, int nthreads=0)} 2594\index{ImageBufAlgo!contrast_remap} \indexapi{contrast_remap} 2595 2596Return (or copy into {\cf dst}) pixel values that are a contrast-remap 2597of the corresponding values of the {\cf src} image, transforming pixel 2598value domain [black, white] to range [min, max], either linearly or with 2599optional application of a smooth sigmoidal remapping (if scontrast != 1.0). 2600 2601\smallskip 2602\noindent Examples: 2603\begin{code} 2604 A = ImageBuf('tahoe.tif'); 2605 2606 # Simple linear remap that stretches input 0.1 to black, and input 2607 # 0.75 to white. 2608 linstretch = ImageBufAlgo.contrast_remap (A, black=0.1, white=0.75) 2609 2610 // Remapping 0->1 and 1->0 inverts the colors of the image, 2611 // equivalent to ImageBufAlgo.invert(). 2612 inverse = ImageBufAlgo.contrast_remap (A, black=1.0, white=0.0) 2613 2614 // Use a sigmoid curve to add contrast but without any hard cutoffs. 2615 // Use a contrast parameter of 5.0. 2616 sigmoid = ImageBufAlgo.contrast_remap (a, contrast=5.0) 2617\end{code} 2618\apiend 2619 2620\apiitem{ImageBuf ImageBufAlgo.{\ce color_map} (src, srcchannel, \\ 2621\bigspc\bigspc nknots, channels, knots, roi=ROI.All, nthreads=0) \\ 2622ImageBuf ImageBufAlgo.{\ce color_map} (src, srcchannel, \\ 2623\bigspc\bigspc mapname, roi=ROI.All, nthreads=0) \\[1.0ex] 2624bool ImageBufAlgo.{\ce color_map} (dst, src, srcchannel, \\ 2625\bigspc\bigspc nknots, channels, knots, roi=ROI.All, nthreads=0) \\ 2626bool ImageBufAlgo.{\ce color_map} (dst, src, srcchannel, \\ 2627\bigspc\bigspc mapname, roi=ROI.All, nthreads=0)} 2628\index{ImageBufAlgo!color_map} \indexapi{color_map} 2629Return an image (or copy into {\cf dst}) pixel values determined by applying 2630the color map to the values of {\cf src}, using either the channel specified 2631by {\cf srcchannel}, or the luminance of {\cf src}'s RGB if {\cf srcchannel} 2632is -1. 2633 2634In the first variant, the values linearly-interpolated color map are 2635given by the tuple {\cf knots[nknots*channels]}. 2636 2637In the second variant, just the name of a color map is specified. Recognized 2638map names include: \qkw{inferno}, \qkw{viridis},\qkw{magma}, \qkw{plasma}, 2639all of which are perceptually uniform, strictly increasing in luminance, 2640look good when converted to grayscale, and work for people with all types of 2641colorblindness. Also supported are the following color maps that do not have 2642those desirable qualities (and are this not recommended): \qkw{blue-red}, 2643\qkw{spectrum}, and \qkw{heat}. In all cases, the implied {\cf channels} is 26443. 2645 2646\smallskip 2647\noindent Examples: 2648\begin{code} 2649 heatmap = ImageBufAlgo.color_map (ImageBuf("a.jpg"), -1, "inferno") 2650 2651 heatmap = ImageBufAlgo.color_map (ImageBuf("a.jpg"), -1, 3, 3, 2652 (0.25, 0.25, 0.25, 0, 0.5, 0, 1, 0, 0)) 2653\end{code} 2654\apiend 2655 2656 2657\apiitem{ImageBuf ImageBufAlgo.{\ce clamp} (src, min, max, 2658 bool clampalpha01=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)\\ 2659bool ImageBufAlgo.{\ce clamp} (dst, src, min, max, 2660 bool clampalpha01=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} 2661\index{ImageBufAlgo!clamp} \indexapi{clamp} 2662 2663Copy pixels while clamping 2664between the {\cf min} and {\cf max} values. The {\cf min} and {\cf max} 2665may either be tuples (one min and max value per channel), or single 2666{\cf floats} (same value for all channels). Additionally, if 2667{\cf clampalpha01} is {\cf True}, then any alpha 2668channel is clamped to the 0--1 range. 2669 2670\smallskip 2671\noindent Examples: 2672\begin{code} 2673 # Clamp image buffer A in-place to the [0,1] range for all channels. 2674 ImageBufAlgo.clamp (A, A, 0.0, 1.0) 2675\end{code} 2676\apiend 2677 2678 2679\apiitem{ImageBuf ImageBufAlgo.{\ce rangecompress} (src, useluma=False, \\ 2680 \bigspc\bigspc roi=ROI.All, nthreads=0) \\ 2681bool ImageBufAlgo.{\ce rangecompress} (dst, src, useluma=False, \\ 2682 \bigspc\bigspc roi=ROI.All, nthreads=0) \\[1.0ex] 2683ImageBuf ImageBufAlgo.{\ce rangeexpand} (src, useluma=False, \\ 2684 \bigspc\bigspc roi=ROI.All, nthreads=0)\\ 2685bool ImageBufAlgo.{\ce rangeexpand} (dst, src, useluma=False, \\ 2686 \bigspc\bigspc roi=ROI.All, nthreads=0)} 2687\index{ImageBufAlgo!rangecompress} \indexapi{rangecompress} 2688\index{ImageBufAlgo!rangeexpand} \indexapi{rangeexpand} 2689 2690Copy from {\cf src}, compressing (logarithmically) or expanding 2691(by the inverse of the compressive transformation) the range of pixel 2692values. Alpha and z channels are copied but not transformed. 2693 2694If {\cf useluma} is {\cf True}, the luma of the first three channels (presumed 2695to be R, G, and B) are used to compute a single scale factor for all 2696color channels, rather than scaling all channels individually (which 2697could result in a big color shift when performing {\cf rangecompress} 2698and {\cf rangeexpand}). 2699 2700\smallskip 2701\noindent Examples: 2702\begin{code} 2703 # Resize the image to 640x480, using a Lanczos3 filter, which 2704 # has negative lobes. To prevent those negative lobes from 2705 # producing ringing or negative pixel values for HDR data, 2706 # do range compression, then resize, then re-expand the range. 2707 2708 # 1. Read the original image 2709 Src = ImageBuf ("tahoeHDR.exr") 2710 2711 # 2. Range compress to a logarithmic scale 2712 Compressed = ImageBufAlgo.rangecompress (Src) 2713 2714 # 3. Now do the resize 2715 roi = ROI (0, 640, 0, 480, 0, 1, 0, Compressed.nchannels) 2716 Dst = ImageBufAlgo.resize (Compressed, "lanczos3", 6.0, roi) 2717 2718 # 4. Expand range to be linear again (operate in-place) 2719 ImageBufAlgo.rangeexpand (Dst, Dst) 2720\end{code} 2721\apiend 2722 2723 2724\apiitem{ImageBuf ImageBufAlgo.{\ce over} (A, B, roi=ROI.All, nthreads=0)\\ 2725bool ImageBufAlgo.{\ce over} (dst, A, B, roi=ROI.All, nthreads=0)} 2726\index{ImageBufAlgo!over} \indexapi{over} 2727 2728Composite \ImageBuf\ {\cf A} \emph{over} \ImageBuf\ {\cf B}. 2729 2730\smallskip 2731\noindent Examples: 2732\begin{code} 2733 Comp = ImageBufAlgo.over (ImageBuf("fg.exr"), ImageBuf("bg.exr")) 2734\end{code} 2735\apiend 2736 2737 2738\apiitem{ImageBuf ImageBufAlgo.{\ce zover} (A, B, bool z_zeroisinf=False,\\ 2739 \bigspc\bigspc roi=ROI.All, nthreads=0\\ 2740bool ImageBufAlgo.{\ce zover} (dst, A, B, bool z_zeroisinf=False,\\ 2741 \bigspc\bigspc roi=ROI.All, nthreads=0)} 2742\index{ImageBufAlgo!zover} \indexapi{zover} 2743 2744Composite \ImageBuf\ {\cf A} and \ImageBuf\ {\cf B} using their respective 2745$Z$ channels to decide which is in front on a pixel-by-pixel basis. 2746 2747\smallskip 2748\noindent Examples: 2749\begin{code} 2750 Comp = ImageBufAlgo.zover (ImageBuf("fg.exr"), ImageBuf("bg.exr")) 2751\end{code} 2752\apiend 2753 2754 2755 2756\subsection{Image comparison and statistics} 2757\label{sec:iba:py:stats} 2758 2759 2760\apiitem{PixelStats ImageBufAlgo.{\ce computePixelStats} (src, roi=ROI.All, nthreads=0)} 2761\index{ImageBufAlgo!computePixelStats} \indexapi{computePixelStats} 2762 2763Compute statistics about the ROI of the image {\cf src}. 2764The {\cf PixelStats} structure is defined as contining the following 2765data fields: {\cf min}, {\cf max}, {\cf avg}, {\cf stddev}, 2766{\cf nancount}, {\cf infcount}, {\cf finitecount}, {\cf sum}, {\cf sum2}, 2767each of which is a \emph{tuple} with one value for each channel of the image. 2768 2769\smallskip 2770\noindent Examples: 2771\begin{code} 2772 A = ImageBuf("a.exr") 2773 stats = ImageBufAlgo.computePixelStats (A) 2774 print " min = ", stats.min 2775 print " max = ", stats.max 2776 print " average = ", stats.avg 2777 print " standard deviation = ", stats.stddev 2778 print " # NaN values = ", stats.nancount 2779 print " # Inf values = ", stats.infcount 2780 print " # finite values = ", stats.finitecount 2781\end{code} 2782\apiend 2783 2784 2785\apiitem{CompareResults ImageBufAlgo.{\ce compare} (A, B, failthresh, warnthresh, 2786 \\ \bigspc\bigspc roi=ROI.All, nthreads=0)} 2787\index{ImageBufAlgo!compare} \indexapi{compare} 2788 2789Numerically compare two \ImageBuf's, {\cf A} and {\cf B}. The {\cf failthresh} 2790and {\cf warnthresh} supply failure and warning difference thresholds. 2791The return value is a {\cf CompareResults} object, 2792which is defined as a class having the following members: 2793\begin{code} 2794 meanerror, rms_error, PSNR, maxerror # error statistics 2795 maxx, maxy, maxz, maxc # pixel of biggest difference 2796 nwarn, nfail # number of warnings and failures 2797 error # True if there was an error 2798\end{code} 2799 2800\smallskip 2801\noindent Examples: 2802\begin{code} 2803 A = ImageBuf ("a.exr") 2804 B = ImageBuf ("b.exr") 2805 comp = ImageBufAlgo.compare (A, B, 1.0/255.0, 0.0) 2806 if comp.nwarn == 0 and comp.nfail == 0 : 2807 print "Images match within tolerance" 2808 else : 2809 print comp.nfail, "failures,", comp.nwarn, " warnings." 2810 print "Average error was " , comp.meanerror 2811 print "RMS error was" , comp.rms_error 2812 print "PSNR was" , comp.PSNR 2813 print "largest error was ", comp.maxerror 2814 print " on pixel", (comp.maxx, comp.maxy, comp.maxz) 2815 print " channel", comp.maxc 2816\end{code} 2817\apiend 2818 2819 2820\apiitem{tuple ImageBufAlgo.{\ce isConstantColor} (src, threshold=0.0, roi=ROI.All, nthreads=0)} 2821\index{ImageBufAlgo!isConstantColor} \indexapi{isConstantColor} 2822 2823If all pixels of {\cf src} within the ROI have the same values (for the 2824subset of channels described by {\cf roi}), return a tuple giving that 2825color (one {\cf float} for each channel), otherwise return {\cf None}. 2826 2827\smallskip 2828\noindent Examples: 2829\begin{code} 2830 A = ImageBuf ("a.exr") 2831 color = ImageBufAlgo.isConstantColor (A) 2832 if color != None : 2833 print "The image has the same value in all pixels:", color 2834 else : 2835 print "The image is not a solid color." 2836\end{code} 2837\apiend 2838 2839 2840\apiitem{bool ImageBufAlgo.{\ce isConstantChannel} (src, channel, val, \\ 2841 \bigspc\bigspc threshold=0.0, roi=ROI.All, nthreads=0)} 2842\index{ImageBufAlgo!isConstantChannel} \indexapi{isConstantChannel} 2843 2844Returns {\cf True} if all pixels of {\cf src} within the ROI have the 2845given {\cf channel} value {\cf val}. 2846 2847\smallskip 2848\noindent Examples: 2849\begin{code} 2850 A = ImageBuf ("a.exr") 2851 alpha = A.spec.alpha_channel 2852 if alpha < 0 : 2853 print "The image does not have an alpha channel" 2854 elif ImageBufAlgo.isConstantChannel (A, alpha, 1.0) : 2855 print "The image has alpha = 1.0 everywhere" 2856 else : 2857 print "The image has alpha < 1 in at least one pixel" 2858\end{code} 2859\apiend 2860 2861 2862\apiitem{bool ImageBufAlgo.{\ce isMonochrome} (src, threshold=0.0, 2863 roi=ROI.All, nthreads=0)} 2864\index{ImageBufAlgo!isMonochrome} \indexapi{isMonochrome} 2865 2866Returns {\cf True} if the image is monochrome within the ROI. 2867 2868\smallskip 2869\noindent Examples: 2870\begin{code} 2871 A = ImageBuf ("a.exr") 2872 roi = A.roi 2873 roi.chend = min (3, roi.chend) # only test RGB, not alpha 2874 if ImageBufAlgo.isMonochrome (A, roi) : 2875 print "a.exr is really grayscale" 2876\end{code} 2877\apiend 2878 2879 2880\begin{comment} 2881\apiitem{bool ImageBufAlgo.{\ce color_count} (src, imagesize_t *count,\\ 2882 \bigspc int ncolors, const float *color, const float *eps=NULL, \\ 2883 \bigspc roi=ROI.All, nthreads=0)} 2884\index{ImageBufAlgo!color_count} \indexapi{color_count} 2885 2886Count how many pixels in the image (within the ROI) match a list of colors. 2887The colors to match are in: 2888 2889\begin{code} 2890 colors[0 ... nchans-1] 2891 colors[nchans ... 2*nchans-1] 2892 ... 2893 colors[(ncolors-1)*nchans ... (ncolors*nchans)-1] 2894\end{code} 2895 2896\noindent and so on, a total of {\cf ncolors} consecutively stored 2897colors of {\cf nchans} channels each ({\cf nchans} is the number of 2898channels in the image, itself, it is not passed as a parameter). 2899 2900 2901The values in {\cf eps[0..nchans-1]} are the error tolerances for a 2902match, for each channel. Setting {\cf eps[c]} to 2903{\cf numeric_limits<float>::max()} will effectively make it ignore the 2904channel. Passing {\cf eps == NULL} will be interpreted as a tolerance 2905of 0.001 for all channels (requires exact matches for 8 bit images, but 2906allows a wee bit of imprecision for {\cf float} images. 2907 2908\smallskip 2909\noindent Examples: 2910\begin{code} 2911 A = ImageBuf ("a.exr") 2912 n = A.nchannels 2913 2914 # Try to match two colors: pure red and green 2915 std::vector<float> colors (2*n, numeric_limits<float>::max()); 2916 colors[0] = 1.0; colors[1] = 0.0; colors[2] = 0.0; 2917 colors[n+0] = 0.0; colors[n+1] = 1.0; colors[n+2] = 0.0; 2918 2919 const int ncolors = 2; 2920 imagesize_t count[ncolors]; 2921 ImageBufAlgo.color_count (A, count, ncolors); 2922 print "Number of red pixels : ", count[0] 2923 print "Number of green pixels : ", count[1] 2924\end{code} 2925\apiend 2926 2927 2928\apiitem{bool {\ce color_range_check} (src, 2929 imagesize_t *lowcount, \\ \bigspc imagesize_t *highcount, imagesize_t 2930 *inrangecount, \\ 2931 \bigspc const float *low, const float *high, \\ 2932 \bigspc roi=ROI.All, nthreads=0)} 2933\index{ImageBufAlgo!color_range_check} \indexapi{color_range_check} 2934 2935Count how many pixels in the image (within the ROI) are outside the 2936value range described by {\cf low[roi.chbegin..roi.chend-1]} and 2937{\cf high[roi.chbegin..roi.chend-1]} 2938as the low and high acceptable values for each color channel. 2939 2940The number of pixels containing values that fall below the lower bound 2941will be stored in {\cf *lowcount}, the number of pixels containing 2942values that fall above the upper bound will be stored in 2943{\cf *highcount}, and the number of pixels for which all channels fell 2944within the bounds will be stored in {\cf *inrangecount}. Any of these 2945may be NULL, which simply means that the counts need not be collected or 2946stored. 2947 2948\smallskip 2949\noindent Examples: 2950\begin{code} 2951 A = ImageBuf ("a.exr") 2952 ROI roi = get_roi (A.spec()) 2953 roi.chend = std::min (roi.chend, 4); # only compare RGBA 2954 2955 float low[] = {0, 0, 0, 0}; 2956 float high[] = {1, 1, 1, 1}; 2957 2958 imagesize_t lowcount, highcount, inrangecount; 2959 ImageBufAlgo.color_range_check (A, &lowcount, &highcount, &inrangecount, 2960 low, high, roi); 2961 print lowcount, " pixels had components < 0" 2962 print highcount, " pixels had components > 1" 2963 print inrangecount, " pixels were fully within [0,1] range" 2964\end{code} 2965\apiend 2966\end{comment} 2967 2968 2969\apiitem{std::string ImageBufAlgo.{\ce computePixelHashSHA1} (src, 2970 extrainfo = "", \\ 2971 \bigspc\bigspc roi=ROI.All, blocksize=0, nthreads=0)} 2972\index{ImageBufAlgo!computePixelHashSHA1} \indexapi{computePixelHashSHA1} 2973 2974Compute the SHA-1 byte hash for all the pixels in the ROI of {\cf src}. 2975 2976\smallskip 2977\noindent Examples: 2978\begin{code} 2979 A = ImageBuf ("a.exr") 2980 hash = ImageBufAlgo.computePixelHashSHA1 (A, blocksize=64) 2981\end{code} 2982\apiend 2983 2984 2985\apiitem{tuple {\ce histogram} (src, channel=0, bins=256, min=0.0, max=1.0, \\ 2986\bigspc ignore_empty=False, roi=ROI.All, nthreads=0)} 2987\index{ImageBufAlgo!histogram} \indexapi{histogram} 2988\apiend 2989 2990Computes a histogram of the given {\cf channel} of image {\cf src}, within 2991the ROI, returning a tuple of length {\cf bins} containing count of pixels 2992whose value was in each of the equally-sized range bins between {\cf min} 2993and {\cf max}. If {\cf ignore_empty} is {\cf True}, pixels that are empty 2994(all channels 0 including alpha) will not be counted in the total. 2995 2996 2997 2998\subsection{Convolutions} 2999\label{sec:iba:py:convolutions} 3000 3001\apiitem{ImageBuf ImageBufAlgo.{\ce make_kernel} (name, width, height, \\ 3002 \bigspc\bigspc depth=1.0, normalize=True)} 3003\index{ImageBufAlgo!make_kernel} \indexapi{make_kernel} 3004Create a 1-channel {\cf float} image of the named kernel 3005and dimensions. If {\cf normalize} is {\cf True}, the values will be 3006normalized so that they sum to $1.0$. 3007 3008If {\cf depth} $> 1$, a volumetric kernel will be created. Use with 3009caution! 3010 3011Kernel names can be: \qkw{gaussian}, \qkw{sharp-gaussian}, \qkw{box}, 3012\qkw{triangle}, \qkw{mitchell}, \qkw{blackman-harris}, \qkw{b-spline}, 3013\qkw{catmull-rom}, \qkw{lanczos3}, \qkw{cubic}, \qkw{keys}, \qkw{simon}, 3014\qkw{rifman}, \qkw{disk}, \qkw{binomial}, \qkw{laplacian}. Note that 3015\qkw{catmull-rom} and \qkw{lanczos3} are fixed-size kernels that don't 3016scale with the width, and are therefore probably less useful in most 3017cases. 3018 3019\smallskip 3020\noindent Examples: 3021\begin{code} 3022 K = ImageBufAlgo.make_kernel ("gaussian", 5.0, 5.0) 3023\end{code} 3024\apiend 3025 3026 3027\apiitem{ImageBuf ImageBufAlgo.{\ce convolve} (src, kernel, normalize=True, \\ 3028 \bigspc\bigspc roi=ROI.All, nthreads=0)\\ 3029bool ImageBufAlgo.{\ce convolve} (dst, src, kernel, normalize=True, \\ 3030 \bigspc\bigspc roi=ROI.All, nthreads=0)} 3031\index{ImageBufAlgo!convolve} \indexapi{convolve} 3032Replace the given ROI of {\cf dst} with the convolution of {\cf src} and 3033a kernel (also an \ImageBuf). 3034 3035\smallskip 3036\noindent Examples: 3037\begin{code} 3038 # Blur an image with a 5x5 Gaussian kernel 3039 Src = ImageBuf ("tahoe.exr") 3040 K = ImageBufAlgo.make_kernel (K, "gaussian", 5.0, 5.0) 3041 Blurred = ImageBufAlgo.convolve (Src, K) 3042\end{code} 3043\apiend 3044 3045 3046\apiitem{ImageBuf ImageBufAlgo.{\ce laplacian} (src, roi=ROI.All, nthreads=0)\\ 3047bool ImageBufAlgo.{\ce laplacian} (dst, src, roi=ROI.All, nthreads=0)} 3048\index{ImageBufAlgo!laplacian} \indexapi{laplacian} 3049Replace the given ROI of {\cf dst} with the Laplacian of the corresponding 3050part of {\cf src}. 3051 3052\smallskip 3053\noindent Examples: 3054\begin{code} 3055 Src = ImageBuf ("tahoe.exr") 3056 L = ImageBufAlgo.laplacian (Src) 3057\end{code} 3058\apiend 3059 3060 3061\apiitem{ImageBuf ImageBufAlgo.{\ce fft} (src, roi=ROI.All, nthreads=0) \\ 3062bool ImageBufAlgo.{\ce fft} (dst, src, roi=ROI.All, nthreads=0) \\[1.0ex] 3063ImageBuf ImageBufAlgo.{\ce ifft} (src, roi=ROI.All, nthreads=0) \\ 3064bool ImageBufAlgo.{\ce ifft} (dst, src, roi=ROI.All, nthreads=0)} 3065\index{ImageBufAlgo!fft} \indexapi{fft} 3066\index{ImageBufAlgo!ifft} \indexapi{ifft} 3067 3068Compute the forward or inverse discrete Fourier Transform. 3069 3070\smallskip 3071\noindent Examples: 3072\begin{code} 3073 Src = ImageBuf ("tahoe.exr") 3074 3075 # Take the DFT of the first channel of Src 3076 Freq = ImageBufAlgo.fft (Src) 3077 3078 # At this point, Freq is a 2-channel float image (real, imag) 3079 # Convert it back from frequency domain to a spatial iamge 3080 Spatial = ImageBufAlgo.ifft (Freq) 3081\end{code} 3082\apiend 3083 3084 3085\apiitem{ImageBuf ImageBufAlgo.{\ce complex_to_polar} (src, roi=ROI.All, nthreads=0) \\ 3086bool ImageBufAlgo.{\ce complex_to_polar} (dst, src, roi=ROI.All, nthreads=0) \\[1.0ex] 3087ImageBuf ImageBufAlgo.{\ce polar_to_complex} (src, roi=ROI.All, nthreads=0) \\ 3088bool ImageBufAlgo.{\ce polar_to_complex} (dst, src, roi=ROI.All, nthreads=0)} 3089\index{ImageBufAlgo!polar_to_complex} \indexapi{polar_to_complex} 3090\index{ImageBufAlgo!complex_to_polar} \indexapi{complex_to_polar} 3091 3092Transform a 2-channel image from complex (real, imaginary) representation 3093to polar (amplitude, phase), or vice versa. 3094 3095\smallskip 3096\noindent Examples: 3097\begin{code} 3098 Polar = ImageBuf ("polar.exr") 3099 3100 Complex = ImageBufAlgo.polar_to_complex (Polar) 3101 3102 # At this point, Complex is a 2-channel complex image (real, imag) 3103 # Convert it back from frequency domain to a spatial iamge 3104 Spatial = ImageBufAlgo.ifft (Complex) 3105\end{code} 3106\apiend 3107 3108 3109 3110\subsection{Image Enhancement / Restoration} 3111\label{sec:iba:py:enhance} 3112 3113\apiitem{ImageBuf ImageBufAlgo.{\ce fixNonFinite} (src, 3114 mode=NONFINITE_BOX3, \\ \bigspc\bigspc\spc roi=ROI.All, nthreads=0)\\ 3115bool ImageBufAlgo.{\ce fixNonFinite} (dst, src, 3116 mode=NONFINITE_BOX3, \\ \bigspc\bigspc\spc roi=ROI.All, nthreads=0)} 3117\index{ImageBufAlgo!fixNonFinite} \indexapi{fixNonFinite} 3118 3119Copy pixel values from {\cf src} and repair any non-finite ({\cf NaN} or {\cf 3120Inf}) pixels. 3121 3122How the non-finite values are repaired is specified by one of the 3123following modes: \\ 3124{\cf OpenImageIO.NONFINITE_NONE}, \\ 3125{\cf OpenImageIO.NONFINITE_BLACK} \\ 3126{\cf OpenImageIO.NONFINITE_BOX3} 3127 3128\smallskip 3129\noindent Examples: 3130\begin{code} 3131 Src = ImageBuf ("tahoe.exr") 3132 ImageBufAlgo.fixNonFinite (Src, Src, OpenImageIO.NONFINITE_BOX3) 3133\end{code} 3134\apiend 3135 3136 3137\apiitem{ImageBuf ImageBufAlgo.{\ce fillholes_pushpull} (src, roi=ROI.All, nthreads=0) \\ 3138bool ImageBufAlgo.{\ce fillholes_pushpull} (dst, src, roi=ROI.All, nthreads=0)} 3139\index{ImageBufAlgo!fillholes_pushpull} \indexapi{fillholes_pushpull} 3140 3141Copy the specified ROI of {\cf src} and fill any 3142holes (pixels where alpha $< 1$) with plausible values using a push-pull 3143technique. The {\cf src} image must have 3144an alpha channel. The {\cf dst} image will end up with a copy of src, but 3145will have an alpha of 1.0 everywhere, and any place where the alpha 3146of src was < 1, dst will have a pixel color that is a plausible 3147``filling'' of the original alpha hole. 3148 3149\smallskip 3150\noindent Examples: 3151\begin{code} 3152 Src = ImageBuf ("holes.exr") 3153 Filled = ImageBufAlgo.fillholes_pushpull (Src) 3154\end{code} 3155\apiend 3156 3157 3158\apiitem{bool ImageBufAlgo.{\ce median_filter} (dst, src, width=3, height=-1, \\ 3159 \bigspc\spc roi=ROI.All, nthreads=0)} 3160\index{ImageBufAlgo!median_filter} \indexapi{median_filter} 3161 3162 3163Replace the given ROI of {\cf dst} with the 3164${\mathit width} \times {\mathit height}$ median filter of the corresponding 3165region of {\cf src} using the ``unsharp mask'' technique. 3166 3167\smallskip 3168\noindent Examples: 3169\begin{code} 3170 Noisy = ImageBuf ("tahoe.exr") 3171 Clean = ImageBuf () 3172 ImageBufAlgo.median_filter (Clean, Noisy, 3, 3) 3173\end{code} 3174\apiend 3175 3176 3177\apiitem{ImageBuf ImageBufAlgo.{\ce dilate} (src, width=3, height=-1, roi=ROI.All, nthreads=0) \\ 3178bool ImageBufAlgo.{\ce dilate} (dst, src, width=3, height=-1, roi=ROI.All, nthreads=0) \\[1.0ex] 3179ImageBuf ImageBufAlgo.{\ce erode} (src, width=3, height=-1, roi=ROI.All, nthreads=0) \\ 3180bool ImageBufAlgo.{\ce erode} (dst, src, width=3, height=-1, roi=ROI.All, nthreads=0) } 3181\index{ImageBufAlgo!dilate} \indexapi{dilate} 3182\index{ImageBufAlgo!erode} \indexapi{erode} 3183 3184Compute a dilated or eroded version of the corresponding region of {\cf src}. 3185 3186\smallskip 3187\noindent Examples: 3188\begin{code} 3189 Source = ImageBuf ("source.tif") 3190 Dilated = ImageBufAlgo.dilate (Source, 3, 3) 3191\end{code} 3192\apiend 3193 3194 3195\apiitem{ImageBuf ImageBufAlgo.{\ce unsharp_mask} (src, kernel="gaussian", width=3.0, \\ 3196 \bigspc\spc contrast=1.0, threshold=0.0, roi=ROI.All, nthreads=0)\\ 3197bool ImageBufAlgo.{\ce unsharp_mask} (dst, src, kernel="gaussian", width=3.0, \\ 3198 \bigspc\spc contrast=1.0, threshold=0.0, roi=ROI.All, nthreads=0)} 3199\index{ImageBufAlgo!unsharp_mask} \indexapi{unsharp_mask} 3200 3201Compute a sharpened version of the corresponding region of {\cf src} using 3202the ``unsharp mask'' technique. 3203 3204\smallskip 3205\noindent Examples: 3206\begin{code} 3207 Blurry = ImageBuf ("tahoe.exr") 3208 Sharp = ImageBufAlgo.unsharp_mask (Blurry, "gaussian", 5.0) 3209\end{code} 3210\apiend 3211 3212 3213 3214\subsection{Color manipulation} 3215\label{sec:iba:py:color} 3216 3217\apiitem{ImageBuf ImageBufAlgo.{\ce colorconvert} (src, fromspace, tospace, unpremult=True, \\ 3218 \bigspc\bigspc context_key="", context_value="", \\ 3219 \bigspc\bigspc colorconfig="", roi=ROI.All, nthreads=0) \\ 3220bool ImageBufAlgo.{\ce colorconvert} (dst, src, fromspace, tospace, unpremult=True, \\ 3221 \bigspc\bigspc context_key="", context_value="", \\ 3222 \bigspc\bigspc colorconfig="", roi=ROI.All, nthreads=0) 3223} 3224\index{ImageBufAlgo!colorconvert} \indexapi{colorconvert} 3225Apply a color transform to the pixel values. 3226 3227\smallskip 3228\noindent Examples: 3229\begin{code} 3230 Src = ImageBuf ("tahoe.jpg") 3231 Dst = ImageBufAlgo.colorconvert (Src, "sRGB", "linear") 3232\end{code} 3233\apiend 3234 3235 3236\apiitem{ImageBuf ImageBufAlgo.{\ce colormatrixtransform} (src, M, unpremult=True, \\ 3237 \bigspc\bigspc roi=ROI.All, nthreads=0) \\ 3238bool ImageBufAlgo.{\ce colormatrixtransform} (dst, src, M, unpremult=True, \\ 3239 \bigspc\bigspc roi=ROI.All, nthreads=0) 3240} 3241\index{ImageBufAlgo!colormatrixtransform} \indexapi{colormatrixtransform} 3242\NEW % 2.1 3243Apply a $4 \times 4$ matrix color transform to the pixel values. The matrix 3244can be any tuple of 16 float values. 3245 3246\smallskip 3247\noindent Examples: 3248\begin{code} 3249 Src = ImageBuf ("tahoe.jpg") 3250 M = ( .8047379, .5058794, -.3106172, 0, 3251 -.3106172, .8047379, .5058794, 0, 3252 .5058794, -.3106172, .8047379, 0, 3253 0, 0, 0, 1) 3254 Dst = ImageBufAlgo.colormatrixtransform (Src, M) 3255\end{code} 3256\apiend 3257 3258 3259\apiitem{ImageBuf ImageBufAlgo.{\ce ociolook} (src, looks, fromspace, tospace, \\ 3260 \bigspc\bigspc inverse=False, unpremult=True, \\ 3261 \bigspc\bigspc context_key="", context_value="", colorconfig="", \\ 3262 \bigspc\bigspc roi=ROI.All, nthreads=0)\\ 3263bool ImageBufAlgo.{\ce ociolook} (dst, src, looks, fromspace, tospace, \\ 3264 \bigspc\bigspc inverse=False, unpremult=True, \\ 3265 \bigspc\bigspc context_key="", context_value="", colorconfig="", \\ 3266 \bigspc\bigspc roi=ROI.All, nthreads=0)} 3267\index{ImageBufAlgo!ociolook} \indexapi{ociolook} 3268Apply an OpenColorIO ``look'' transform to the pixel values. 3269 3270\smallskip 3271\noindent Examples: 3272\begin{code} 3273 Src = ImageBuf ("tahoe.jpg") 3274 Dst = ImageBufAlgo.ociolook (Src, "look", "vd8", "lnf", 3275 context_key="SHOT", context_value="pe0012") 3276\end{code} 3277\apiend 3278 3279 3280\apiitem{ImageBuf ImageBufAlgo.{\ce ociodisplay} (src, display, view, \\ 3281 \bigspc\bigspc fromspace="", looks="", unpremult=True, \\ 3282 \bigspc\bigspc context_key="", context_value="", colorconfig="", \\ 3283 \bigspc\bigspc roi=ROI.All, nthreads=0) \\ 3284bool ImageBufAlgo.{\ce ociodisplay} (dst, src, display, view, \\ 3285 \bigspc\bigspc fromspace="", looks="", unpremult=True, \\ 3286 \bigspc\bigspc context_key="", context_value="", colorconfig="", \\ 3287 \bigspc\bigspc roi=ROI.All, nthreads=0)} 3288\index{ImageBufAlgo!ociodisplay} \indexapi{ociodisplay} 3289Apply an OpenColorIO ``display'' transform to the pixel values. 3290 3291\smallskip 3292\noindent Examples: 3293\begin{code} 3294 Src = ImageBuf ("tahoe.exr") 3295 Dst = ImageBufAlgo.ociodisplay (Src, "sRGB", "Film", "lnf", 3296 context_key="SHOT", context_value="pe0012") 3297\end{code} 3298\apiend 3299 3300 3301\apiitem{ImageBuf ImageBufAlgo.{\ce ociofiletransform} (src, name, \\ 3302 \bigspc\bigspc unpremult=True, invert=False, colorconfig="", \\ 3303 \bigspc\bigspc roi=ROI.All, nthreads=0) \\ 3304bool ImageBufAlgo.{\ce ociofiletransform} (dst, src, name, \\ 3305 \bigspc\bigspc unpremult=True, invert=False, colorconfig="", \\ 3306 \bigspc\bigspc roi=ROI.All, nthreads=0)} 3307\index{ImageBufAlgo!ociofiletransform} \indexapi{ociofiletransform} 3308Apply an OpenColorIO ``file'' transform to the pixel values. 3309In-place operations ({\cf dst} and {\cf src} being the same image) 3310are supported. 3311 3312\smallskip 3313\noindent Examples: 3314\begin{code} 3315 Src = ImageBuf ("tahoe.exr") 3316 Dst = ImageBufAlgo.ociofiletransform (Src, "foottransform.csp") 3317\end{code} 3318\apiend 3319 3320 3321\apiitem{ImageBuf ImageBufAlgo.{\ce unpremult} (src, roi=ROI.All, nthreads=0) \\ 3322bool ImageBufAlgo.{\ce unpremult} (dst, src, roi=ROI.All, nthreads=0) \\[1.0ex] 3323ImageBuf ImageBufAlgo.{\ce premult} (src, roi=ROI.All, nthreads=0) \\ 3324bool ImageBufAlgo.{\ce premult} (dst, src, roi=ROI.All, nthreads=0)} 3325\index{ImageBufAlgo!unpremult} \indexapi{unpremult} 3326\index{ImageBufAlgo!premult} \indexapi{premult} 3327Copy pixels from {\cf src} to {\cf dst}, and un-premultiply (or 3328premultiply) the colors by alpha. 3329 3330\smallskip 3331\noindent Examples: 3332\begin{code} 3333 # Convert in-place from associated alpha to unassociated alpha 3334 A = ImageBuf ("a.exr") 3335 ImageBufAlgo.unpremult (A, A) 3336\end{code} 3337\apiend 3338 3339 3340 3341\subsection{Import / export} 3342\label{sec:iba:py:importexport} 3343 3344\apiitem{bool ImageBufAlgo.{\ce make_texture} (mode, input,\\ 3345\bigspc\bigspc outputfilename, config=ImageSpec())} 3346\index{ImageBufAlgo!make_texture} \indexapi{make_texture} 3347 3348Turn an input image (either an \ImageBuf or a string giving a filename) 3349into a tiled, MIP-mapped, texture file and write to the 3350file named by ({\cf outputfilename}). The {\cf mode} describes what type of texture file we 3351are creating and may be one of the following: 3352 3353\noindent \begin{tabular}{p{4in}} 3354{\cf OpenImageIO.MakeTxTexture} \\ 3355{\cf OpenImageIO.MakeTxEnvLatl} \\ 3356{\cf OpenImageIO.MakeTxEnvLatlFromLightProbe} \\ 3357\end{tabular} 3358 3359The {\cf config}, if supplied, is an \ImageSpec that contains all the 3360information and special instructions for making the texture. The full list 3361of supported configuration options is given in 3362Section~\ref{sec:iba:importexport}. 3363 3364\smallskip 3365\noindent Examples: 3366\begin{code} 3367 # This command line: 3368 # maketx in.exr --hicomp --filter lanczos3 --opaque-detect \ 3369 # -o texture.exr 3370 # is equivalent to: 3371 3372 Input = ImageBuf ("in.exr") 3373 config = ImageSpec() 3374 config.attribute ("maketx:highlightcomp", 1) 3375 config.attribute ("maketx:filtername", "lanczos3") 3376 config.attribute ("maketx:opaque_detect", 1) 3377 ImageBufAlgo.make_texture (oiio.MakeTxTexture, Input, 3378 "texture.exr", config) 3379\end{code} 3380\apiend 3381 3382 3383\apiitem{ImageBuf ImageBufAlgo::{\ce capture_image} (cameranum, convert = OpenImageIO.UNKNOWN)} 3384\index{ImageBufAlgo!capture_image} \indexapi{capture_image} 3385Capture a still image from a designated camera. 3386 3387\smallskip 3388\noindent Examples: 3389\begin{code} 3390 WebcamImage = ImageBufAlgo.capture_image (0, OpenImageIO.UINT8) 3391 WebcamImage.write ("webcam.jpg") 3392\end{code} 3393\apiend 3394 3395 3396\subsection{Functions specific to deep images} 3397 3398\apiitem{ImageBuf ImageBufAlgo.{\ce deepen} (src, zvalue=1.0, roi=ROI.All, nthreads=0)\\ 3399bool ImageBufAlgo.{\ce deepen} (dst, src, zvalue=1.0, roi=ROI.All, nthreads=0)} 3400\index{ImageBufAlgo!deepen} \indexapi{deepen} \index{deep images} 3401 3402Convert a flat image to a deep one that has one depth sample per pixel 3403(but no depth samples for the pixels corresponding to those in the source 3404image that have infinite \qkw{Z} or that had 0 for all color channels and no 3405\qkw{Z} channel). 3406 3407\smallskip 3408\noindent Examples: 3409\begin{code} 3410 Deep = ImageBufAlgo.deepen (ImageBuf("az.exr")) 3411\end{code} 3412\apiend 3413 3414 3415\apiitem{ImageBuf ImageBufAlgo.{\ce flatten} (src, roi=ROI.All, nthreads=0)\\ 3416bool ImageBufAlgo.{\ce flatten} (dst, src, roi=ROI.All, nthreads=0)} 3417\index{ImageBufAlgo!flatten} \indexapi{flatten} \index{deep images} 3418 3419Composite the depth samples within each pixel of ``deep'' \ImageBuf\ {\cf 3420src} to produce a ``flat'' \ImageBuf. 3421 3422\smallskip 3423\noindent Examples: 3424\begin{code} 3425 Flat = ImageBufAlgo.flatten (ImageBuf("deepalpha.exr")) 3426\end{code} 3427\apiend 3428 3429\apiitem{ImageBuf ImageBufAlgo.{\ce deep_merge} (A, B, occlusion_cull, roi=ROI.All, nthreads=0) \\ 3430bool ImageBufAlgo.{\ce deep_merge} (dst, A, B, occlusion_cull, roi=ROI.All, nthreads=0)} 3431\index{ImageBufAlgo!deep_merge} \indexapi{deep_merge} \index{deep images} 3432 3433Merge the samples of two \emph{deep} images {\cf A} and {\cf B} into a deep 3434result. If {\cf occlusion_cull} is {\cf True}, samples beyond 3435the first opaque sample will be discarded, otherwise they will be kept. 3436 3437\smallskip 3438\noindent Examples: 3439\begin{code} 3440 DeepA = ImageBuf("hardsurf.exr") 3441 DeepB = ImageBuf("volume.exr") 3442 Merged = ImageBufAlgo.deep_merge (DeepA, DeepB) 3443\end{code} 3444\apiend 3445 3446\apiitem{ImageBuf ImageBufAlgo.{\ce deep_holdout} (src, holdout, roi=ROI.All, nthreads=0) \\ 3447bool ImageBufAlgo.{\ce deep_holdout} (dst, src, holdout, roi=ROI.All, nthreads=0)} 3448\index{ImageBufAlgo!deep_holdout} \indexapi{deep_holdout} \index{deep images} 3449 3450Return the pixels of {\cf src}, but only copying the 3451samples that are closer than the opaque frontier of image {\cf holdout}. 3452That is, {\cf holdout} will serve as a depth holdout mask, but no samples 3453from {\cf holdout} will actually be copied to {\cf dst}. 3454 3455\smallskip 3456\noindent Examples: 3457\begin{code} 3458 Img = ImageBuf("image.exr") 3459 Mask = ImageBuf("mask.exr") 3460 Thresholded = ImageBufAlgo.deep_holdout (Img, Mask) 3461\end{code} 3462\apiend 3463 3464 3465\subsection*{Other ImageBufAlgo methods that understand deep images} 3466 3467In addition to the previously described methods that are specific to 3468deep images, the following \ImageBufAlgo methods (described in their 3469respective sections) work with deep inputs: 3470 3471\medskip 3472 3473\noindent 3474{\cf ImageBufAlgo.add} \\ 3475{\cf ImageBufAlgo.channels} \\ 3476{\cf ImageBufAlgo.compare} \\ 3477{\cf ImageBufAlgo.computePixelStats} \\ 3478{\cf ImageBufAlgo.crop} \\ 3479{\cf ImageBufAlgo.div} \\ 3480{\cf ImageBufAlgo.fixNonFinite} \\ 3481{\cf ImageBufAlgo.mul} \\ 3482{\cf ImageBufAlgo.nonzero_region} \\ 3483{\cf ImageBufAlgo.resample} \\ 3484{\cf ImageBufAlgo.sub} \\ 3485 3486 3487\newpage 3488\section{Miscellaneous Utilities} 3489\label{sec:pythonmiscapi} 3490 3491In the main {\cf OpenImageIO} module, there are a number of values and 3492functions that are useful. These correspond to the C++ API functions 3493explained in Section~\ref{sec:miscapi}, please refer there for details. 3494 3495\apiitem{int {\ce openimageio_version}} 3496The \product version number, 10000 for each 3497major version, 100 for each minor version, 1 for each patch. For 3498example, \product 1.2.3 would return a value of 10203. 3499\apiend 3500 3501\apiitem{str {\ce geterror} ()} 3502Retrieves the latest global error. 3503\apiend 3504 3505\apiitem{bool {\ce attribute} (name, typedesc, value) \\ 3506bool {\ce attribute} (name, int_value) \\ 3507bool {\ce attribute} (name, float_value) \\ 3508bool {\ce attribute} (name, str_value)} 3509Sets a global attribute (see Section~\ref{sec:miscapi} for details), 3510returning {\cf True} upon success, or {\cf False} if it was not a 3511recognized attribute. 3512 3513\noindent Example: 3514\begin{code} 3515 oiio.attribute ("threads", 0) 3516\end{code} 3517\apiend 3518 3519\apiitem{{\ce getattribute} (name, typedesc) \\ 3520{\ce get_int_attribute} (name, defaultval=0) \\ 3521{\ce get_float_attribute} (name, defaultval=0.0) \\ 3522{\ce get_string_attribute} (name, defaultval="")} 3523Retrieves an attribute value from the named set of global OIIO options. (See 3524Section~\ref{sec:globalattribute}.) The {\cf getattribute()} function 3525returns the value regardless of type, or {\cf None} if the attribute does 3526not exist. The typed variety will only succeed if the attribute is actually 3527of that type specified. Type varity with the type in the name also takes a 3528default value. 3529 3530\noindent Example: 3531\begin{code} 3532 formats = oiio.get_string_attribute ("format_list") 3533\end{code} 3534\apiend 3535 3536 3537 3538\section{Python Recipes} 3539\label{sec:pythonrecipes} 3540 3541This section illustrates the Python syntax for doing many common image 3542operations from Python scripts, but that aren't already given as examples 3543in the earlier function descriptions. All example code fragments assume the 3544following boilerplate: 3545 3546\begin{code} 3547 #!/usr/bin/env python 3548 3549 import OpenImageIO as oiio 3550 from OpenImageIO import ImageBuf, ImageSpec, ImageBufAlgo 3551\end{code} 3552 3553 3554\subsubsection*{Subroutine to create a constant-colored image} 3555\begin{code} 3556 # Create an ImageBuf holding a n image of constant color, given the 3557 # resolution, data format (defaulting to UINT8), fill value, and image 3558 # origin. 3559 def make_constimage (xres, yres, chans=3, format=oiio.UINT8, value=(0,0,0), 3560 xoffset=0, yoffset=0) : 3561 spec = ImageSpec (xres,yres,chans,format) 3562 spec.x = xoffset 3563 spec.y = yoffset 3564 b = ImageBuf (spec) 3565 oiio.ImageBufAlgo.fill (b, value) 3566 return b 3567\end{code} 3568 3569\noindent The image is returned as an \ImageBuf, then up to the caller 3570what to do with it next. 3571 3572\subsubsection*{Subroutine to save an image to disk, printing errors} 3573\begin{code} 3574 # Save an ImageBuf to a given file name, with optional forced image format 3575 # and error handling. 3576 def write_image (image, filename, format=oiio.UNKNOWN) : 3577 if not image.has_error : 3578 image.write (filename, format) 3579 if image.has_error : 3580 print "Error writing", filename, ":", image.geterror() 3581\end{code} 3582 3583 3584\subsubsection*{Converting between file formats} 3585 3586\begin{code} 3587 img = ImageBuf ("input.png") 3588 write_image (img, "output.tif") 3589\end{code} 3590 3591 3592\subsubsection*{Comparing two images and writing a difference image} 3593 3594\begin{code} 3595 A = ImageBuf ("A.tif") 3596 B = ImageBuf ("B.tif") 3597 compresults = ImageBufAlgo.compare (A, B, 1.0e-6, 1.0e-6) 3598 if compresults.nfail > 0 : 3599 print "Images did not match, writing difference image diff.tif" 3600 diff = ImageBufAlgo.absdiff (A, B) 3601 image_write (diff, "diff.tif") 3602\end{code} 3603 3604 3605\subsubsection*{Changing the data format or bit depth} 3606 3607\begin{code} 3608 img = ImageBuf ("input.exr") 3609 # presume that it's a "half" OpenEXR file 3610 # write it back out as a "float" file: 3611 write_image (img, "output.exr", oiio.FLOAT) 3612\end{code} 3613 3614 3615\subsubsection*{Changing the compression} 3616 3617The following command converts writes a TIFF file, specifically using 3618LZW compression: 3619 3620\begin{code} 3621 img = ImageBuf ("in.tif") 3622 img.specmod().attribute ("compression", "lzw") 3623 write_image (img, "compressed.tif") 3624\end{code} 3625 3626The following command writes its results as a JPEG file at a 3627compression quality of 50 (pretty severe compression): 3628 3629\begin{code} 3630 img = ImageBuf ("big.jpg") 3631 img.specmod().attribute ("quality", 50) 3632 write_image (img, "small.jpg") 3633\end{code} 3634 3635 3636\subsubsection*{Converting between scanline and tiled images} 3637 3638\begin{code} 3639 img = ImageBuf ("scan.tif") 3640 img.set_write_tiles (16, 16) 3641 write_image (img, "tile.tif") 3642 3643 img = ImageBuf ("tile.tif") 3644 img.set_write_tiles (0, 0) 3645 write_image (img, "scan.tif") 3646\end{code} 3647 3648 3649\subsubsection*{Adding captions or metadata} 3650 3651\begin{code} 3652 img = ImageBuf ("foo.jpg") 3653 # Add a caption: 3654 img.specmod().attribute ("ImageDescription", "Hawaii vacation") 3655 # Add keywords: 3656 img.specmod().attribute ("keywords", "volcano,lava") 3657 write_image (img, "foo.jpg") 3658\end{code} 3659 3660 3661\subsubsection*{Changing image boundaries} 3662 3663\noindent Change the origin of the pixel data window: 3664\begin{code} 3665 img = ImageBuf ("in.exr") 3666 img.set_origin (256, 80) 3667 write_image (img, "offset.exr") 3668\end{code} 3669 3670\noindent Change the display window: 3671\begin{code} 3672 img = ImageBuf ("in.exr") 3673 img.set_full (16, 1040, 16, 784) 3674 write_image (img, "out.exr") 3675\end{code} 3676 3677\noindent Change the display window to match the data window: 3678\begin{code} 3679 img = ImageBuf ("in.exr") 3680 img.set_full (img.roi()) 3681 write_image (img, "out.exr") 3682\end{code} 3683 3684\noindent Cut (trim and extract) a 128x128 region whose upper left corner 3685is at location (900,300), moving the result to the origin (0,0) of the image 3686plane and setting the display window to the new pixel data window: 3687\begin{code} 3688 img = ImageBuf ("in.exr") 3689 b = ImageBufAlgo.cut (img, oiio.ROI(900,1028,300,428)) 3690 write_image (b, "out.exr") 3691\end{code} 3692 3693 3694\subsubsection*{Extract just the named channels from a complicted many-channel 3695image, and add an alpha channel that is 1 everywhere} 3696\begin{code} 3697 img = ImageBuf ("allmyaovs.exr") 3698 b = ImageBufAlgo.channels (img, ("spec.R", "spec.G", "spec.B", 1.0)) 3699 write_image (b, "spec.tif") 3700\end{code} 3701 3702 3703\subsubsection*{Fade 30\% of the way between two images} 3704 3705\begin{code} 3706 a = ImageBufAlgo.mul (ImageBuf("A.exr"), 0.7) 3707 b = ImageBufAlgo.mul (ImageBuf("B.exr"), 0.3) 3708 fade = ImageBufAlgo.add (a, b) 3709 write_image (fade, "fade.exr") 3710\end{code} 3711 3712 3713\subsubsection*{Composite of small foreground over background, with offset} 3714 3715\begin{code} 3716 fg = ImageBuf ("fg.exr") 3717 fg.set_origin (512, 89) 3718 bg = ImageBuf ("bg.exr") 3719 comp = ImageBufAlgo.over (fg, bg) 3720 write_image (comp, "composite.exr") 3721\end{code} 3722 3723 3724 3725 3726\index{Python|)} 3727 3728\chapwidthend 3729