free-image 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +5 -0
- data/LICENSE +21 -0
- data/README.rdoc +99 -0
- data/Rakefile +47 -0
- data/cookbook.rdoc +239 -0
- data/free-image.gemspec +30 -0
- data/lib/free-image.rb +101 -0
- data/lib/free-image/bitmap.rb +154 -0
- data/lib/free-image/enums/color_types.rb +24 -0
- data/lib/free-image/enums/dithers.rb +24 -0
- data/lib/free-image/enums/filters.rb +12 -0
- data/lib/free-image/enums/formats.rb +84 -0
- data/lib/free-image/enums/image_types.rb +36 -0
- data/lib/free-image/errors.rb +44 -0
- data/lib/free-image/modules/conversions.rb +166 -0
- data/lib/free-image/modules/helper.rb +42 -0
- data/lib/free-image/modules/icc.rb +41 -0
- data/lib/free-image/modules/information.rb +305 -0
- data/lib/free-image/modules/modify.rb +261 -0
- data/lib/free-image/modules/pixels.rb +135 -0
- data/lib/free-image/modules/transforms.rb +83 -0
- data/lib/free-image/palette.rb +44 -0
- data/lib/free-image/scanline.rb +151 -0
- data/lib/free-image/sources/abstract_source.rb +172 -0
- data/lib/free-image/sources/file.rb +115 -0
- data/lib/free-image/sources/io.rb +154 -0
- data/lib/free-image/sources/memory.rb +189 -0
- data/lib/free-image/types/boolean.rb +14 -0
- data/lib/free-image/types/complex.rb +9 -0
- data/lib/free-image/types/ffi.rb +14 -0
- data/lib/free-image/types/rgb16.rb +11 -0
- data/lib/free-image/types/rgb_quad.rb +82 -0
- data/lib/free-image/types/rgb_triple.rb +42 -0
- data/lib/free-image/types/rgba16.rb +12 -0
- data/lib/free-image/types/rgbaf.rb +12 -0
- data/lib/free-image/types/rgbf.rb +11 -0
- data/test/cookbook.rb +46 -0
- data/test/images/gradient.png +0 -0
- data/test/images/lena.png +0 -0
- data/test/images/lena.tiff +0 -0
- data/test/images/lena_flipped.png +0 -0
- data/test/images/lena_rescale_bicubic.png +0 -0
- data/test/images/lena_rescale_bilinear.png +0 -0
- data/test/images/lena_rescale_box.png +0 -0
- data/test/images/lena_rescale_bspline.png +0 -0
- data/test/images/lena_rescale_catmullrom.png +0 -0
- data/test/images/lena_rescale_lanczos3.png +0 -0
- data/test/images/lena_rotate_45.png +0 -0
- data/test/images/lena_rotate_ex_45_masked.png +0 -0
- data/test/images/lena_rotate_ex_45_mirrored.png +0 -0
- data/test/images/lena_rotate_ex_45_top_left.png +0 -0
- data/test/images/lena_thumbnail.png +0 -0
- data/test/images/lena_thumbnail_border_enlarge.png +0 -0
- data/test/images/lena_thumbnail_border_paste.png +0 -0
- data/test/images/lena_thumbnail_border_scanline.png +0 -0
- data/test/images/not_an_image.txt +0 -0
- data/test/images/sample.png +0 -0
- data/test/images/sample_composite_color.png +0 -0
- data/test/test_bitmap.rb +43 -0
- data/test/test_conversions.rb +86 -0
- data/test/test_file.rb +51 -0
- data/test/test_free_image.rb +15 -0
- data/test/test_helper.rb +35 -0
- data/test/test_information.rb +118 -0
- data/test/test_io.rb +53 -0
- data/test/test_memory.rb +65 -0
- data/test/test_modify.rb +59 -0
- data/test/test_palette.rb +45 -0
- data/test/test_pixels.rb +62 -0
- data/test/test_rgb_quad.rb +26 -0
- data/test/test_scanline.rb +65 -0
- data/test/test_suite.rb +19 -0
- data/test/test_transforms.rb +30 -0
- metadata +169 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
module FreeImage
|
2
|
+
#DLL_API BYTE *DLL_CALLCONV FreeImage_GetBits(FIBITMAP *dib);
|
3
|
+
attach_function('FreeImage_GetBits', [:pointer], :pointer)
|
4
|
+
|
5
|
+
#DLL_API BYTE *DLL_CALLCONV FreeImage_GetScanLine(FIBITMAP *dib, int scanline);
|
6
|
+
attach_function('FreeImage_GetScanLine', [:pointer, :int], :pointer)
|
7
|
+
|
8
|
+
#DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value);
|
9
|
+
attach_function('FreeImage_GetPixelIndex', [:pointer, :uint, :uint, :pointer], FreeImage::Boolean)
|
10
|
+
|
11
|
+
#DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelIndex(FIBITMAP *dib, unsigned x, unsigned y, BYTE *value);
|
12
|
+
attach_function('FreeImage_SetPixelIndex', [:pointer, :uint, :uint, :pointer], FreeImage::Boolean)
|
13
|
+
|
14
|
+
#DLL_API BOOL DLL_CALLCONV FreeImage_GetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value);
|
15
|
+
attach_function('FreeImage_GetPixelColor', [:pointer, :uint, :uint, :pointer], FreeImage::Boolean)
|
16
|
+
|
17
|
+
#DLL_API BOOL DLL_CALLCONV FreeImage_SetPixelColor(FIBITMAP *dib, unsigned x, unsigned y, RGBQUAD *value);
|
18
|
+
attach_function('FreeImage_SetPixelColor', [:pointer, :uint, :uint, :pointer], FreeImage::Boolean)
|
19
|
+
|
20
|
+
# == Summary
|
21
|
+
#
|
22
|
+
# The \Pixel module provides methods that allow you to read, write and work pixel-by-pixel
|
23
|
+
# with image data. \FreeImage not only can work with standard bitmap data
|
24
|
+
# (e.g. 1-, 4-, 8-, 16-, 24- and 32-bit) but also with scientific data such as
|
25
|
+
# 16-bit greyscale images, or images made up of long, double or complex values
|
26
|
+
# (often used in signal and image processing algorithms).
|
27
|
+
#
|
28
|
+
# The \FreeImage coordinate system is upside down relative to usual graphics
|
29
|
+
# conventions. Thus, the scanlines are stored upside down, with the first
|
30
|
+
# scan in memory being the bottommost scan in the image.
|
31
|
+
#
|
32
|
+
# For additional information, please refer to the FreeImage::Scanline documentation.
|
33
|
+
#
|
34
|
+
module Pixels
|
35
|
+
# Returns the data-bits of the bitmap. It is up to you to interpret these bytes
|
36
|
+
# correctly, according to the results of Information#bits_per_pixel, Information#red_mask,
|
37
|
+
# Information#green_mask and Information#blue_mask.
|
38
|
+
#
|
39
|
+
# If the bitmap does not contain pixel data (see Information#has_pixels),
|
40
|
+
# nil will be returned.
|
41
|
+
#
|
42
|
+
# For a performance reason, the address returned by FreeImage_GetBits is aligned on
|
43
|
+
# a 16 bytes alignment boundary
|
44
|
+
#
|
45
|
+
def bits
|
46
|
+
ptr = FreeImage.FreeImage_GetBits(self)
|
47
|
+
FreeImage.check_last_error
|
48
|
+
ptr.read_string
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the requested row of image data as a FreeImage::Scanline instance.
|
52
|
+
#
|
53
|
+
# If the bitmap does not contain pixel data (see Information#has_pixels),
|
54
|
+
# nil will be returned.
|
55
|
+
def scanline(index)
|
56
|
+
unless (0...self.height).include?(index)
|
57
|
+
raise(RangeError, "Index must be between 0 and #{self.height - 1}")
|
58
|
+
end
|
59
|
+
ptr = FreeImage.FreeImage_GetScanLine(self, index)
|
60
|
+
FreeImage.check_last_error
|
61
|
+
|
62
|
+
ptr ? Scanline.new(self, index, ptr) : nil
|
63
|
+
end
|
64
|
+
|
65
|
+
# Gets the pixel index of a palettized image at the specified coordinate.
|
66
|
+
#
|
67
|
+
# == Parameters
|
68
|
+
# x:: The pixel position in horizontal direction
|
69
|
+
# y:: The pixel position in vertical direction.
|
70
|
+
#
|
71
|
+
def pixel_index(x, y)
|
72
|
+
byte_type = FreeImage.find_type(:byte)
|
73
|
+
ptr = FFI::MemoryPointer.new(byte_type)
|
74
|
+
result = FreeImage.FreeImage_GetPixelIndex(self, x, y, ptr)
|
75
|
+
FreeImage.check_last_error
|
76
|
+
return nil unless result
|
77
|
+
|
78
|
+
data = ptr.read_bytes(byte_type.size)
|
79
|
+
if byte_type.size == 1
|
80
|
+
data.ord
|
81
|
+
else
|
82
|
+
data
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Sets the pixel index of a palettized image at the specified coordinate.
|
87
|
+
#
|
88
|
+
# == Parameters
|
89
|
+
# x:: The pixel position in horizontal direction
|
90
|
+
# y:: The pixel position in vertical direction.
|
91
|
+
#
|
92
|
+
# The function returns true on success and false otherwise.
|
93
|
+
#
|
94
|
+
def set_pixel_index(x, y, index)
|
95
|
+
byte_type = FreeImage.find_type(:byte)
|
96
|
+
ptr = FFI::MemoryPointer.new(byte_type.size)
|
97
|
+
if byte_type.size == 1
|
98
|
+
ptr.put_bytes(0, index.chr, 0, byte_type.size)
|
99
|
+
else
|
100
|
+
ptr.put_bytes(0, index.to_s, 0, byte_type.size)
|
101
|
+
end
|
102
|
+
result = FreeImage.FreeImage_SetPixelIndex(self, x, y, ptr)
|
103
|
+
FreeImage.check_last_error
|
104
|
+
result
|
105
|
+
end
|
106
|
+
|
107
|
+
# Gets the pixel color of a 16-, 24- or 32-bit image at the specified coordinate.
|
108
|
+
#
|
109
|
+
# == Parameters
|
110
|
+
# x:: The pixel position in horizontal direction
|
111
|
+
# y:: The pixel position in vertical direction.
|
112
|
+
#
|
113
|
+
def pixel_color(x, y)
|
114
|
+
color = RGBQuad.new
|
115
|
+
result = FreeImage.FreeImage_GetPixelColor(self, x, y, color)
|
116
|
+
FreeImage.check_last_error
|
117
|
+
result ? color : nil
|
118
|
+
end
|
119
|
+
|
120
|
+
# Sets the pixel color of a 16-, 24- or 32-bit image at the specified coordinate.
|
121
|
+
#
|
122
|
+
# == Parameters
|
123
|
+
# x:: The pixel position in horizontal direction
|
124
|
+
# y:: The pixel position in vertical direction.
|
125
|
+
# color:: The new color as a RGBAQuad instance.
|
126
|
+
#
|
127
|
+
# The function returns true on success and false otherwise.
|
128
|
+
#
|
129
|
+
def set_pixel_color(x, y, color)
|
130
|
+
result = FreeImage.FreeImage_SetPixelColor(self, x, y, color)
|
131
|
+
FreeImage.check_last_error
|
132
|
+
result
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module FreeImage
|
2
|
+
# DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, const void *bkcolor FI_DEFAULT(NULL));
|
3
|
+
attach_function('FreeImage_Rotate', [:pointer, :double, :pointer], :pointer)
|
4
|
+
|
5
|
+
# DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask);
|
6
|
+
attach_function('FreeImage_RotateEx', [:pointer, :double, :double, :double, :double, :double, FreeImage::Boolean], :pointer)
|
7
|
+
|
8
|
+
# DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib);
|
9
|
+
attach_function('FreeImage_FlipHorizontal', [:pointer], FreeImage::Boolean)
|
10
|
+
|
11
|
+
# DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical(FIBITMAP *dib);
|
12
|
+
attach_function('FreeImage_FlipVertical', [:pointer], FreeImage::Boolean)
|
13
|
+
|
14
|
+
module Transforms
|
15
|
+
# call-seq:
|
16
|
+
# bitmap.rotate(angle, bk_color) -> bitmap
|
17
|
+
#
|
18
|
+
# Rotates an image around the center of the image area by means of 3 shears.
|
19
|
+
# The rotated image retains the same size and aspect ratio of source image
|
20
|
+
# (the resulting image size is usually bigger), so that this function should
|
21
|
+
# be used when rotating an image by 90°, 180° or 270°.
|
22
|
+
#
|
23
|
+
# When the angle value isn’t an integer multiple of 90°, the background is
|
24
|
+
# filled with the supplied bkcolor parameter. When bkcolor is nil, the
|
25
|
+
# default value, the background is filled with a black.
|
26
|
+
#
|
27
|
+
# == Parameters
|
28
|
+
#
|
29
|
+
# angle:: Specifies the angle of rotation in degrees
|
30
|
+
# bk_color:: The color used to fill the background.
|
31
|
+
#
|
32
|
+
def rotate(angle, bk_color = nil)
|
33
|
+
ptr = FreeImage.FreeImage_Rotate(self, angle, bk_color)
|
34
|
+
FreeImage.check_last_error
|
35
|
+
self.class.new(ptr)
|
36
|
+
end
|
37
|
+
|
38
|
+
# call-seq:
|
39
|
+
# bitmap.rotate_ex(aangle, x_shift, y_shift, x_origin, y_origin, use_mask = false) -> bitmap
|
40
|
+
#
|
41
|
+
# Rotates an image using a 3rd order (cubic) B-Spline. The rotated image will have
|
42
|
+
# the same width and height as the source image, so that this function is better
|
43
|
+
# suited for computer vision and robotics.
|
44
|
+
#
|
45
|
+
# == Parameters:
|
46
|
+
#
|
47
|
+
# angle:: Specifies the angle of rotation in degrees
|
48
|
+
# x_shift:: Specifies horizonal image translation
|
49
|
+
# y_shift:: Specifies vertical image translation
|
50
|
+
# x_origin:: Specifies the x coordinate of the center of rotation
|
51
|
+
# y_origin:: Specifies the y coordinate of the center of rotation
|
52
|
+
# use_mask:: When true, irrelevant parts of the image are set to black,
|
53
|
+
# otherwise, a mirroring technique is used to fill irrelevant pixels.
|
54
|
+
#
|
55
|
+
def rotate_ex(angle, x_shift, y_shift, x_origin, y_origin, use_mask = false);
|
56
|
+
ptr = FreeImage.FreeImage_RotateEx(self, angle, x_shift, y_shift, x_origin, y_origin, use_mask)
|
57
|
+
FreeImage.check_last_error
|
58
|
+
self.class.new(ptr)
|
59
|
+
end
|
60
|
+
|
61
|
+
# call-seq:
|
62
|
+
# bitmap.flip_horizontal -> boolean
|
63
|
+
#
|
64
|
+
# Flip the input image horizontally along the vertical axis.
|
65
|
+
#
|
66
|
+
def flip_horizontal!
|
67
|
+
result = FreeImage.FreeImage_FlipHorizontal(self)
|
68
|
+
FreeImage.check_last_error
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
# call-seq:
|
73
|
+
# bitmap.flip_vertical -> boolean
|
74
|
+
#
|
75
|
+
# Flip the input image vertically horizontally along the horizontal axis.
|
76
|
+
#
|
77
|
+
def flip_vertical!
|
78
|
+
result = FreeImage.FreeImage_FlipHorizontal(self)
|
79
|
+
FreeImage.check_last_error
|
80
|
+
result
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module FreeImage
|
3
|
+
#DLL_API unsigned DLL_CALLCONV FreeImage_GetColorsUsed(FIBITMAP *dib);
|
4
|
+
attach_function('FreeImage_GetColorsUsed', [:pointer], :ulong)
|
5
|
+
|
6
|
+
#DLL_API RGBQUAD *DLL_CALLCONV FreeImage_GetPalette(FIBITMAP *dib);
|
7
|
+
attach_function('FreeImage_GetPalette', [:pointer], :pointer)
|
8
|
+
|
9
|
+
# Represents a bitmaps palette. If the bitmap doesn’t have a palette (i.e. when
|
10
|
+
# its pixel bit depth is greater than 8), this function returns nil.
|
11
|
+
class Palette
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
def initialize(bitmap)
|
15
|
+
# Keep reference to bitmap so its not gc'ed
|
16
|
+
@bitmap = bitmap
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the palette-size for palletised bitmaps, and 0 for high-colour bitmaps.
|
20
|
+
def size
|
21
|
+
result = FreeImage.FreeImage_GetColorsUsed(@bitmap)
|
22
|
+
FreeImage.check_last_error
|
23
|
+
result
|
24
|
+
end
|
25
|
+
alias :colors_used :size
|
26
|
+
|
27
|
+
# Returns the index color as an instance of FreeImage::RGBQuad
|
28
|
+
def [](index)
|
29
|
+
unless (0..self.size).include?(index)
|
30
|
+
raise(RangeError, "Value is out of range 0..#{self.size}. Value: #{index}")
|
31
|
+
end
|
32
|
+
|
33
|
+
ptr = FreeImage.FreeImage_GetPalette(@bitmap)
|
34
|
+
FreeImage.check_last_error
|
35
|
+
RGBQuad.new(ptr[index])
|
36
|
+
end
|
37
|
+
|
38
|
+
def each
|
39
|
+
size.times do |i|
|
40
|
+
yield (self[i])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module FreeImage
|
2
|
+
#DLL_API BYTE *DLL_CALLCONV FreeImage_GetScanLine(FIBITMAP *dib, int scanline);
|
3
|
+
attach_function('FreeImage_GetScanLine', [:pointer, :int], :pointer)
|
4
|
+
|
5
|
+
# == Summary
|
6
|
+
# Scanlines provide low level access to image data.
|
7
|
+
# The only lower-level access is working with the actual raw bytes, which you can do
|
8
|
+
# via the FreeeImage::Bitmap#bytes method, but its not recommended.
|
9
|
+
#
|
10
|
+
# A scanline represents one row of image data, starting from the bottom. You can
|
11
|
+
# get a scanline via the Freeimage::Pixels#scanline method.
|
12
|
+
#
|
13
|
+
# To understand how scanlines work, you have to first understand that image data
|
14
|
+
# is stored differently depending on the {image type}[FreeImage.image_types]
|
15
|
+
# and the {bits per pixel}[FreeImage::Information#bits_per_pixel]. Thus, when
|
16
|
+
# you call reeImage::Scanline#[] with an index, you will get back a different
|
17
|
+
# object depending on the image type and bit depth.
|
18
|
+
#
|
19
|
+
# In a :bitmap image, possible bit depths are 1-, 4-, 8-, 16-, 24-, 32-, 48-,
|
20
|
+
# 64-, 96- and 128-bit.
|
21
|
+
#
|
22
|
+
# * 1-bit DIBs are stored using each bit as an index into the color table. The most
|
23
|
+
# significant bit is the leftmost pixel. This is not currently supported.
|
24
|
+
# * 4-bit DIBs are stored with each 4 bits representing an index into the color table. The
|
25
|
+
# most significant nibble is the leftmost pixel. This is not currently supported.
|
26
|
+
# * 8-bit DIBs are the easiest to store because each byte is an index into the color table.
|
27
|
+
# This is not currently supported.
|
28
|
+
# * 24-bit DIBs have every 3 bytes representing a color, using the same ordering as the
|
29
|
+
# RGBTRIPLE structure. Colors are represented using FreeImage::RGBTriple.
|
30
|
+
# * 32-bit DIB have every 4 bytes representing a color associated to a alpha value (used
|
31
|
+
# to indicate transparency). Colors are represented using FreeImage::RGBTriple.
|
32
|
+
#
|
33
|
+
# Non standard image types such as short, long, float or double do not have a color
|
34
|
+
# table. Pixels are stored in a similar way as 8-bit DIB.
|
35
|
+
#
|
36
|
+
# Complex image types are stored in a similar way as 24- or 32bit DIB. Colors are
|
37
|
+
# represented using FreeImage::Complex.
|
38
|
+
#
|
39
|
+
# 16-bit RGB[A] image types are stored in a similar way as 24-bit
|
40
|
+
# DIBs. Colors are represented using FreeImage::RGB16 or FreeImage::RFBA16.
|
41
|
+
#
|
42
|
+
# Float RGB[A] image types are stored in a similar way 32bit
|
43
|
+
# DIBs. Colors are represented using FreeImage::RGBF or FreeImage::RFBAF.
|
44
|
+
#
|
45
|
+
class Scanline
|
46
|
+
include Enumerable
|
47
|
+
|
48
|
+
# Creates a new scanline instance
|
49
|
+
#
|
50
|
+
# == Parameters
|
51
|
+
# bitmap:: An instance of FreeImage::Bitmap
|
52
|
+
# index:: The index of the scanline, must be between 0 and the image
|
53
|
+
# pixel heigh minus one.
|
54
|
+
# ptr:: A pointer to the raw pixel data.
|
55
|
+
#
|
56
|
+
# Generally you do not want to call this method directly. Instead, use
|
57
|
+
# FreeImage::Bitmap#scanline.
|
58
|
+
#
|
59
|
+
def initialize(bitmap, index, ptr)
|
60
|
+
@bitmap = bitmap
|
61
|
+
@index = index
|
62
|
+
@ptr = ptr
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the appropriate color object for the image type and
|
66
|
+
# bit depth. See notes for the FreeImage::Scanline class.
|
67
|
+
#
|
68
|
+
# == Parameters
|
69
|
+
# index:: The index of the scanline, must be between 0 and the image
|
70
|
+
# pixel width minus one.
|
71
|
+
#
|
72
|
+
# Returns the appropriate object for manipulating the data.
|
73
|
+
#
|
74
|
+
def [](index)
|
75
|
+
unless (0...pixelsize).include?(index)
|
76
|
+
raise(RangeError, "Index must be between 0 and #{pixelsize - 1}")
|
77
|
+
end
|
78
|
+
bytes_per_pixel = @bitmap.bits_per_pixel/8
|
79
|
+
|
80
|
+
# Now get the address of the pixel
|
81
|
+
address = @ptr.address + (index * bytes_per_pixel)
|
82
|
+
|
83
|
+
# Now get a pointer to the pixel
|
84
|
+
ptr = FFI::Pointer.new(bytes_per_pixel, address)
|
85
|
+
|
86
|
+
# Now return a nice object to work with
|
87
|
+
color_type.new(ptr)
|
88
|
+
end
|
89
|
+
|
90
|
+
# The width of the image in pixels. Same as FreeImage::Bitmap#width.
|
91
|
+
#
|
92
|
+
def pixelsize
|
93
|
+
@bitmap.width
|
94
|
+
end
|
95
|
+
|
96
|
+
# The width of the image in bytes. Same as FreeImage::Bitmap#pitch.
|
97
|
+
#
|
98
|
+
def bytesize
|
99
|
+
@bitmap.pitch
|
100
|
+
end
|
101
|
+
|
102
|
+
# Iterate over each pixel, returning the appropriate object to manipulate
|
103
|
+
# the underlying data.
|
104
|
+
#
|
105
|
+
def each
|
106
|
+
pixelsize.times do |i|
|
107
|
+
yield (self[i])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def color_type
|
114
|
+
case @bitmap.image_type
|
115
|
+
when :bitmap
|
116
|
+
case @bitmap.bits_per_pixel
|
117
|
+
when 24
|
118
|
+
RGBTriple
|
119
|
+
when 32
|
120
|
+
RGBQuad
|
121
|
+
else
|
122
|
+
raise(ArgumentError, "Not Supported")
|
123
|
+
end
|
124
|
+
when :uint16
|
125
|
+
FFI::UINT16
|
126
|
+
when :int16
|
127
|
+
FFI::INT16
|
128
|
+
when :uint32
|
129
|
+
FFI::UINT32
|
130
|
+
when :int32
|
131
|
+
FFI::INT16
|
132
|
+
when :float
|
133
|
+
FFI::FLOAT
|
134
|
+
when :double
|
135
|
+
FFI::DOUBLE
|
136
|
+
when :complex
|
137
|
+
Complex
|
138
|
+
when :rgb16
|
139
|
+
RGB16
|
140
|
+
when :rgba16
|
141
|
+
RGBA16
|
142
|
+
when :rgbf
|
143
|
+
RGBF
|
144
|
+
when :rgbaf
|
145
|
+
RGBAF
|
146
|
+
else
|
147
|
+
raise(ArgumentError, "Not Supported")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
module FreeImage
|
2
|
+
# == Summary
|
3
|
+
#
|
4
|
+
# FreeImage can load images from a variety of files,
|
5
|
+
# memory or streams. For additional details please see:
|
6
|
+
#
|
7
|
+
# FreeImage::File:: Use to load images from files
|
8
|
+
# FreeImage::Memory:: Use to load images from byte strings
|
9
|
+
# FreeImage::IO:: Use to load images from io streams
|
10
|
+
#
|
11
|
+
class AbstractSource
|
12
|
+
# The Decoder module defines various constants that
|
13
|
+
# control how various image formats are loaded.
|
14
|
+
module Decoder
|
15
|
+
# Load the image header only (not supported by all plugins)
|
16
|
+
FIF_LOADNOPIXELS = 0x8000
|
17
|
+
GIF_DEFAULT = 0x0
|
18
|
+
# Load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
|
19
|
+
GIF_LOAD256 = 0x1
|
20
|
+
# 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
|
21
|
+
GIF_PLAYBACK = 0x2
|
22
|
+
ICO_DEFAULT = 0x0
|
23
|
+
# Loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
|
24
|
+
JPEG_DEFAULT = 0x0
|
25
|
+
# Load the file as fast as possible, sacrificing some quality
|
26
|
+
JPEG_FAST = 0x1
|
27
|
+
# Load the file with the best quality, sacrificing some speed
|
28
|
+
JPEG_ACCURATE = 0x2
|
29
|
+
# Load separated CMYK "as is" (use | to combine with other load flags)
|
30
|
+
JPEG_CMYK = 0x4
|
31
|
+
# Load and rotate according to Exif 'Orientation' tag if available
|
32
|
+
JPEG_EXIFROTATE =0x8
|
33
|
+
PCD_DEFAULT = 0x0
|
34
|
+
# Load the bitmap sized 768 x 512
|
35
|
+
PCD_BASE = 0x1
|
36
|
+
# Load the bitmap sized 384 x 256
|
37
|
+
PCD_BASEDIV4 = 0x2
|
38
|
+
# Load the bitmap sized 192 x 128
|
39
|
+
PCD_BASEDIV16 = 0x3
|
40
|
+
# Loading: avoid gamma correction
|
41
|
+
PNG_IGNOREGAMMA = 0x1
|
42
|
+
PSD_DEFAULT = 0x0
|
43
|
+
# Reads tags for separated CMYK (default is conversion to RGB)
|
44
|
+
PSD_CMYK = 0x1
|
45
|
+
# Reads tags for CIELab (default is conversion to RGB)
|
46
|
+
PSD_LAB = 0x2
|
47
|
+
# Load the file as linear RGB 48-bit
|
48
|
+
RAW_DEFAULT = 0x0
|
49
|
+
# Try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
|
50
|
+
RAW_PREVIEW = 0x1
|
51
|
+
# Load the file as RGB 24-bit
|
52
|
+
RAW_DISPLAY = 0x2
|
53
|
+
# Output a half-size color image
|
54
|
+
RAW_HALFSIZE = 0x4
|
55
|
+
# If set the loader converts RGB555 and ARGB8888 -> RGB888.
|
56
|
+
TARGA_LOAD_RGB888 = 0x1
|
57
|
+
# Reads/stores tags for separated CMYK (use | to combine with compression flags)
|
58
|
+
TIFF_CMYK = 0x1
|
59
|
+
end
|
60
|
+
|
61
|
+
# The Encoder module defines various constants that
|
62
|
+
# control how various image formats are saved.
|
63
|
+
module Encoder
|
64
|
+
BMP_DEFAULT = 0x0
|
65
|
+
BMP_SAVE_RLE = 0x1
|
66
|
+
# Save data as half with piz-based wavelet compression
|
67
|
+
EXR_DEFAULT = 0x0
|
68
|
+
# Save data as float instead of as half (not recommended)
|
69
|
+
EXR_FLOAT = 0x0001
|
70
|
+
# Save with no compression
|
71
|
+
EXR_NONE = 0x0002
|
72
|
+
# Save with zlib compression, in blocks of 16 scan lines
|
73
|
+
EXR_ZIP = 0x0004
|
74
|
+
# Save with piz-based wavelet compression
|
75
|
+
EXR_PIZ = 0x0008
|
76
|
+
# Save with lossy 24-bit float compression
|
77
|
+
EXR_PXR24 = 0x0010
|
78
|
+
# Save with lossy 44% float compression - goes to 22% when combined with EXR_LC
|
79
|
+
EXR_B44 = 0x0020
|
80
|
+
# Save images with one luminance and two chroma channels, rather than as RGB (lossy compression)
|
81
|
+
EXR_LC = 0x0040
|
82
|
+
# Save with a 16:1 rate
|
83
|
+
J2K_DEFAULT = 0x0
|
84
|
+
# Save with a 16:1 rate
|
85
|
+
JP2_DEFAULT = 0x0
|
86
|
+
# Loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
|
87
|
+
JPEG_DEFAULT = 0x0
|
88
|
+
# Save with superb quality (100:1)
|
89
|
+
JPEG_QUALITYSUPERB = 0x80
|
90
|
+
# Save with good quality (75:1)
|
91
|
+
JPEG_QUALITYGOOD = 0x0100
|
92
|
+
# Save with normal quality (50:1)
|
93
|
+
JPEG_QUALITYNORMAL = 0x0200
|
94
|
+
# Save with average quality (25:1)
|
95
|
+
JPEG_QUALITYAVERAGE = 0x0400
|
96
|
+
# Save with bad quality (10:1)
|
97
|
+
JPEG_QUALITYBAD = 0x0800
|
98
|
+
# Save as a progressive-JPEG (use | to combine with other save flags)
|
99
|
+
JPEG_PROGRESSIVE = 0x2000
|
100
|
+
# Save with high 4x1 chroma subsampling (4:1:1)
|
101
|
+
JPEG_SUBSAMPLING_411 = 0x1000
|
102
|
+
# Save with medium 2x2 medium chroma subsampling (4:2:0) - default value
|
103
|
+
JPEG_SUBSAMPLING_420 = 0x4000
|
104
|
+
# Save with low 2x1 chroma subsampling (4:2:2)
|
105
|
+
JPEG_SUBSAMPLING_422 = 0x8000
|
106
|
+
# Save with no chroma subsampling (4:4:4)
|
107
|
+
JPEG_SUBSAMPLING_444 = 0x10000
|
108
|
+
# On saving, compute optimal Huffman coding tables (can reduce a few percent of file size)
|
109
|
+
JPEG_OPTIMIZE = 0x20000
|
110
|
+
# Save basic JPEG, without metadata or any markers
|
111
|
+
JPEG_BASELINE = 0x40000
|
112
|
+
PNG_DEFAULT = 0x0
|
113
|
+
# Save using ZLib level 1 compression flag (default value is 6)
|
114
|
+
PNG_Z_BEST_SPEED = 0x0001
|
115
|
+
# Save using ZLib level 6 compression flag (default recommended value)
|
116
|
+
PNG_Z_DEFAULT_COMPRESSION = 0x0006
|
117
|
+
# Save using ZLib level 9 compression flag (default value is 6)
|
118
|
+
PNG_Z_BEST_COMPRESSION = 0x0009
|
119
|
+
# Save without ZLib compression
|
120
|
+
PNG_Z_NO_COMPRESSION = 0x0100
|
121
|
+
# Save using Adam7 interlacing (use | to combine with other save flags)
|
122
|
+
PNG_INTERLACED = 0x0200
|
123
|
+
PNM_DEFAULT = 0x0
|
124
|
+
# If set the writer saves in RAW format (i.e. P4, P5 or P6)
|
125
|
+
PNM_SAVE_RAW = 0x0
|
126
|
+
# If set the writer saves in ASCII format (i.e. P1, P2 or P3)
|
127
|
+
PNM_SAVE_ASCII = 0x1
|
128
|
+
TARGA_DEFAULT = 0x0
|
129
|
+
# If set, the writer saves with RLE compression
|
130
|
+
TARGA_SAVE_RLE = 0x2
|
131
|
+
TIFF_DEFAULT = 0x0
|
132
|
+
# Reads/stores tags for separated CMYK (use | to combine with compression flags)
|
133
|
+
TIFF_CMYK = 0x0001
|
134
|
+
# Save using PACKBITS compression
|
135
|
+
TIFF_PACKBITS = 0x0100
|
136
|
+
# Save using DEFLATE compression (a.k.a. ZLIB compression)
|
137
|
+
TIFF_DEFLATE = 0x0200
|
138
|
+
# Save using ADOBE DEFLATE compression
|
139
|
+
TIFF_ADOBE_DEFLATE = 0x0400
|
140
|
+
# Save without any compression
|
141
|
+
TIFF_NONE = 0x0800
|
142
|
+
# Save using CCITT Group 3 fax encoding
|
143
|
+
TIFF_CCITTFAX3 = 0x1000
|
144
|
+
# Save using CCITT Group 4 fax encoding
|
145
|
+
TIFF_CCITTFAX4 = 0x2000
|
146
|
+
# Save using LZW compression
|
147
|
+
TIFF_LZW = 0x4000
|
148
|
+
# Save using JPEG compression
|
149
|
+
TIFF_JPEG = 0x8000
|
150
|
+
# Save using LogLuv compression
|
151
|
+
TIFF_LOGLUV = 0x10000
|
152
|
+
end
|
153
|
+
|
154
|
+
# :nodoc: - This method is documented on subclasses
|
155
|
+
def open(format = nil, flags = 0)
|
156
|
+
format ||= self.format
|
157
|
+
|
158
|
+
# Do we know the format?
|
159
|
+
if format == :unknown
|
160
|
+
raise(Error.new(:unknown, "Cannot load :unknown image format"))
|
161
|
+
end
|
162
|
+
|
163
|
+
# Can we load the image?
|
164
|
+
unless FreeImage.FreeImage_FIFSupportsReading(format)
|
165
|
+
raise(Error.new("Cannot load image"))
|
166
|
+
end
|
167
|
+
|
168
|
+
ptr = load(format, flags)
|
169
|
+
Bitmap.new(ptr, self)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|