| OpenGL-Image documentation | Contained in the OpenGL-Image distribution. |
OpenGL::Image::Magick - copyright 2007 Graphcomp - ALL RIGHTS RESERVED Author: Bob "grafman" Free - grafman@graphcomp.com This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
This is a driver module for use with the OpenGL module. While it may be called directly, it will more often be called by the OpenGL::Image abstraction module. Note: OpenGL::Image defaults to this module. This is a subclass of the OpenGL::Image::Common module. Requires the Image::Magick module; 6.3.5 or newer is recommended.
##########
# Check for installed imaging engines
use OpenGL::Image;
my $img = new OpenGL::Image(engine=>'Magick',source=>'MyImage.png');
##########
# Methods defined in the OpenGL::Image::Common module:
# Get native engine object
# Note: must not change image dimensions
my $obj = $img->Native;
$obj->Quantize() if ($obj);
# Alternately (Assuming the native engine supports Blur):
$img->Native->Blur();
# Test if image width is a power of 2
if ($img->IsPowerOf2());
# Test if all listed values are a power of 2
if ($img->IsPowerOf2(@list));
# Get largest power of 2 size within dimensions of image
my $size = $img->GetPowerOf2();
# Get all parameters as a hashref
my $params = $img->Get();
# Get one or more parameter values
my @values = $img->Get(@params);
# Get/Set Pixel values (normalized to 1.0)
my($r,$g,$b,$a) = $img->GetPixel($x,$y);
# Sync cache after done modifying pixels
$img->SetPixel($x,$y,$r,$g,$b,$a);
$frame->Sync();
##########
# Supported parameters:
# source - source image, if defined
# width - width of image in pixels
# height - height of image in pixels
# pixels - number of pixels
# components - number of pixel components
# size - bytes per component
# length - cache size in bytes
# endian - 1 if big endian; otherwise 0
# alpha - 1 if has alpha channel, -1 if has inverted alpha channel; 0 if none
# flipped - 1 bit set if cache scanlines are top to bottom; others reserved
# gl_internalformat - internal GL pixel format. eg: GL_RGBA8, GL_RGBA16
# gl_format - GL pixel format. eg: GL_RGBA, GL_BGRA
# gl_type - GL data type. eg: GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT
##########
# APIs defined in this module:
# Get engine version
my $ver = OpenGL::Image::THIS_MODULE::EngineVersion();
# Get engine description
my $desc = OpenGL::Image::ENGINE_MODULE::EngineDescription();
##########
# Methods defined in this module:
# Sync the image cache after modifying pixels.
# Used by some engines for paged caches; otherwise a NOP.
$img->Sync();
# Return the image's cache as an OpenGL::Array object.
# Note: OGA may change after a cache update
my $oga = $img->GetArray();
# Return a C pointer to the image's cache.
# For use with OpenGL's "_c" APIs.
# Note: pointer may change after a cache update
$img->Ptr();
# Save file - automatically does a Sync before write
$img->Save('MyImage.png');
# Get image blob.
my $blob = $img->GetBlob();
| OpenGL-Image documentation | Contained in the OpenGL-Image distribution. |
############################################################ # # OpenGL::Image::Magick - Copyright 2007 Graphcomp - ALL RIGHTS RESERVED # Author: Bob "grafman" Free - grafman@graphcomp.com # # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # ############################################################ package OpenGL::Image::Magick; require Exporter; use Carp; use vars qw($VERSION $DESCRIPTION @ISA); $VERSION = '1.02'; $DESCRIPTION = qq {Supports optimized internal interfaces to the ImageMagick library.}; use OpenGL::Image::Common; @ISA = qw(Exporter OpenGL::Image::Common); use OpenGL(':constants');
eval 'use Image::Magick'; # Get engine version sub EngineVersion { return $Image::Magick::VERSION; } # Get engine description sub EngineDescription { return $DESCRIPTION; } # Base constructor sub new { my $this = shift; my $class = ref($this) || $this; my $self = new OpenGL::Image::Common(@_); return undef if (!$self); $self->{params}->{engine} = 'Magick'; $self->{params}->{version} = EngineVersion(); $self->{params}->{components} = 4; $self->{params}->{alpha} = 0; $self->{params}->{flipped} = 1; # Use source image if supplied my $img; if ($self->{params}->{source}) { $img = new Image::Magick(); return undef if (!$img); my $stat = $img->Read($self->{params}->{source}); return undef if ($stat); ($self->{params}->{width},$self->{params}->{height}) = $img->Get('Width','Height'); return undef if (!$self->{params}->{width} || !$self->{params}->{height}); $self->{native} = $img; } # Otherwise create uninitialized image else { my $w = $self->{params}->{width}; my $h = $self->{params}->{height}; my $blob = $self->{params}->{blob}; if ($w && $h) { my $dim = $w.'x'.$h; $self->{native} = new Image::Magick(size=>$dim, magick=>'RGBA', depth=>8); } elsif ($blob) { $self->{native} = new Image::Magick(); } return undef if (!$self->{native}); $img = $self->{native}; # Populate with blob if ($blob) { my $stat = $img->BlobToImage($blob); return undef if ($stat); if (!$w || !$h) { ($self->{params}->{width},$self->{params}->{height}) = $img->Get('Width','Height'); } } # Otherwise fill with 'none' else { my $stat = $img->Read('xc:none'); return undef if ($stat); $img->Set(type=>'truecolormatte'); } } my $alpha = $img->Get('matte'); $img->Set('matte'=>'True') if (!$alpha); # Good to go bless($self,$class); # Init params return undef if (!$self->init()); $self->SyncOGA(); return $self; } # Initialize object sub init { my($self) = @_; my $w = $self->{params}->{width}; my $h = $self->{params}->{height}; $self->{params}->{pixels} = $w * $h; my $elements = $self->{params}->{pixels} * $self->{params}->{components}; my $img = $self->{native}; # Use C pointer to image cache, if supported if ($self->{params}->{version} ge '6.3.5') { my $q = $img->Get('quantum'); if ($q == 8) { $self->{params}->{gl_internalformat} = GL_RGBA8; $self->{params}->{gl_type} = GL_UNSIGNED_BYTE; $self->{params}->{size} = 1; } elsif ($q == 16) { $self->{params}->{gl_internalformat} = GL_RGBA16; $self->{params}->{gl_type} = GL_UNSIGNED_SHORT; $self->{params}->{size} = 2; } else { print "Unsupported pixel quantum\n"; } if ($self->{params}->{gl_type}) { $self->{params}->{gl_format} = $self->{params}->{endian} ? GL_RGBA : GL_BGRA; $self->{params}->{length} = $self->{params}->{size} * $elements; $self->{oga} = OpenGL::Array->new_pointer($self->{params}->{gl_type}, $img->GetImagePixels(rows=>$h),$elements); $self->{params}->{alpha} = -1; return $self->{oga}; } } # Fall back to using standard PerlMagick interface $self->{blobs} = 1; $self->{params}->{gl_internalformat} = GL_RGBA8; $self->{params}->{gl_type} = GL_UNSIGNED_BYTE; $self->{params}->{size} = 1; $self->{params}->{gl_format} = GL_RGBA; $self->{params}->{alpha} = 1; $self->{params}->{length} = $self->{params}->{pixels} * $self->{params}->{components} * $self->{params}->{size}; $img->Set(magick=>'RGBA',depth=>8); $self->{oga} = OpenGL::Array->new_scalar($self->{params}->{gl_type}, $img->ImageToBlob(),$elements); return $self->{oga}; } # Sync from GPU framebuffer (OGA/blob) to IM # Call before using native calls sub Sync { my($self) = @_; my $img = $self->{native}; if ($self->{blobs}) { $img->BlobToImage($self->{oga}->retrieve_data()); } else { $img->SyncImagePixels(); } $img->Negate(channel=>'Alpha') if ($self->{params}->{alpha} < 0); $img->Flip(); } # Sync from IM to GPU framebuffer (OGA/blob) # Call after using native calls sub SyncOGA { my($self) = @_; my $img = $self->{native}; $img->Flip(); $img->Negate(channel=>'Alpha') if ($self->{params}->{alpha} < 0); my($w,$h) = $img->Get('width','height'); my $pixels = $w * $h; my $elements = $pixels * $self->{params}->{components}; if ($self->{blobs}) { $img->Set(magick=>'RGBA',depth=>8); $self->{oga} = OpenGL::Array->new_scalar($self->{params}->{gl_type}, $img->ImageToBlob(),$elements); } if ($w == $self->{params}->{width} && $h == $self->{params}->{height}) { return if ($self->{blobs}); $self->{oga}->update_pointer($img->GetImagePixels(rows=>$h)); } $self->{params}->{width} = $w; $self->{params}->{height} = $h; $self->{params}->{pixels} = $pixels; $self->{params}->{length} = $elements * $self->{params}->{size}; return if ($self->{blobs}); $self->{oga} = OpenGL::Array->new_pointer($self->{params}->{gl_type}, $img->GetImagePixels(rows=>$h),$elements); } # Get OpenGL::Array object sub GetArray { my($self) = @_; return $self->{oga}; } # Get C pointer to image cache sub Ptr { my($self) = @_; return undef if (!$self->{oga}); return $self->{oga}->ptr(); } # Save image sub Save { my($self,$file,%user_params) = @_; my $img = $self->{native}; $self->Sync(); my $blob; if ($file) { if ($self->{blobs} && $img->[1]) { $img->[1]->Write(filename=>$file,%user_params); } else { $img->[0]->Write(filename=>$file,%user_params); } } else { %user_params = (magick=>'RGBA',depth=>8) if (!scalar(%user_params)); delete($user_params{filename}); my $clone = $img->Clone(); $clone->Set(%user_params); ($blob) = $clone->ImageToBlob(); } $self->SyncOGA(); return $blob; } # Get image blob sub GetBlob { my($self,%params) = @_; return $self->Save(undef,%params); } 1; __END__