free-image 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,14 @@
|
|
1
|
+
module FreeImage
|
2
|
+
if !self.msvc?
|
3
|
+
typedef :int32, :bool
|
4
|
+
typedef :uint32, :byte
|
5
|
+
typedef :uint16, :word
|
6
|
+
typedef :uint32, :dword
|
7
|
+
typedef :int32, :long
|
8
|
+
else
|
9
|
+
typedef :long, :bool
|
10
|
+
typedef :uchar, :byte
|
11
|
+
typedef :ushort, :word
|
12
|
+
typedef :ulong, :dword
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module FreeImage
|
4
|
+
# Used to specify a color for a :bitmap
|
5
|
+
# {image type}[rdoc-ref:FreeImage.images_types].
|
6
|
+
#--
|
7
|
+
# This structure is packed with pragma (1)
|
8
|
+
class RGBQuad < FFI::Struct
|
9
|
+
if FFI::Platform::BYTE_ORDER == FFI::Platform::LITTLE_ENDIAN
|
10
|
+
layout :blue, :byte, 0,
|
11
|
+
:green, :byte, 1,
|
12
|
+
:red, :byte, 2,
|
13
|
+
:reserved, :byte, 3
|
14
|
+
else
|
15
|
+
layout :red, :byte, 0,
|
16
|
+
:green, :byte, 1,
|
17
|
+
:blue, :byte, 2,
|
18
|
+
:reserved, :byte, 3
|
19
|
+
end
|
20
|
+
|
21
|
+
# Define masks to extract colors from bytes
|
22
|
+
if FFI::Platform::BYTE_ORDER == FFI::Platform::LITTLE_ENDIAN
|
23
|
+
# Little Endian (x86 / MS Windows, Linux) : BGR(A) order
|
24
|
+
RED = 2
|
25
|
+
GREEN = 1
|
26
|
+
BLUE = 0
|
27
|
+
ALPHA = 3
|
28
|
+
RED_MASK = 0x00FF0000
|
29
|
+
GREEN_MASK = 0x0000FF00
|
30
|
+
BLUE_MASK = 0x000000FF
|
31
|
+
ALPHA_MASK = 0xFF000000
|
32
|
+
RED_SHIFT = 16
|
33
|
+
GREEN_SHIFT = 8
|
34
|
+
BLUE_SHIFT = 0
|
35
|
+
ALPHA_SHIFT = 24
|
36
|
+
else
|
37
|
+
# Big Endian (PPC / Linux, MaxOSX) : RGB(A) order
|
38
|
+
RED = 0
|
39
|
+
GREEN = 1
|
40
|
+
BLUE = 2
|
41
|
+
ALPHA = 3
|
42
|
+
RED_MASK = 0xFF000000
|
43
|
+
GREEN_MASK = 0x00FF0000
|
44
|
+
BLUE_MASK = 0x0000FF00
|
45
|
+
ALPHA_MASK = 0x000000FF
|
46
|
+
RED_SHIFT = 24
|
47
|
+
GREEN_SHIFT = 16
|
48
|
+
BLUE_SHIFT = 8
|
49
|
+
ALPHA_SHIFT = 0
|
50
|
+
end
|
51
|
+
RGB_MASK = (RED_MASK | GREEN_MASK | BLUE_MASK)
|
52
|
+
|
53
|
+
# Creates a new RGBQuad color
|
54
|
+
#
|
55
|
+
# == Parameters
|
56
|
+
# red:: Value for red, should be between 0 and 255
|
57
|
+
# green:: Value for green, should be between 0 and 255
|
58
|
+
# blue:: Value for blue, should be between 0 and 255
|
59
|
+
# reserved:: Reserved value, by default is 0
|
60
|
+
def self.create(red, green, blue, reserved = 0)
|
61
|
+
result = self.new
|
62
|
+
result[:red] = red
|
63
|
+
result[:green] = green
|
64
|
+
result[:blue] = blue
|
65
|
+
result[:reserved] = reserved
|
66
|
+
result
|
67
|
+
end
|
68
|
+
|
69
|
+
def eql?(other)
|
70
|
+
other.instance_of?(RGBQuad) and
|
71
|
+
self[:red] == other[:red] and
|
72
|
+
self[:green] == other[:green] and
|
73
|
+
self[:blue] == other[:blue] and
|
74
|
+
self[:reserved] == other[:reserved]
|
75
|
+
end
|
76
|
+
alias :== :eql?
|
77
|
+
|
78
|
+
def to_s
|
79
|
+
"RGBQuad - Red: #{self[:red]}, Green: #{self[:green]}, Blue: #{self[:blue]}, Alpha: #{self[:reserved]}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module FreeImage
|
4
|
+
class RGBTriple < FFI::Struct
|
5
|
+
if FFI::Platform::BYTE_ORDER == FFI::Platform::LITTLE_ENDIAN
|
6
|
+
layout :blue, :byte, 0,
|
7
|
+
:green, :byte, 1,
|
8
|
+
:red, :byte, 2
|
9
|
+
else
|
10
|
+
layout :red, :byte, 0,
|
11
|
+
:green, :byte, 1,
|
12
|
+
:blue, :byte, 2
|
13
|
+
end
|
14
|
+
|
15
|
+
# Creates a new RGBTriple color
|
16
|
+
#
|
17
|
+
# == Parameters
|
18
|
+
# red:: Value for red, should be between 0 and 255
|
19
|
+
# green:: Value for green, should be between 0 and 255
|
20
|
+
# blue:: Value for blue, should be between 0 and 255
|
21
|
+
#
|
22
|
+
def self.create(red, green, blue)
|
23
|
+
result = self.new
|
24
|
+
result[:red] = red
|
25
|
+
result[:green] = green
|
26
|
+
result[:blue] = blue
|
27
|
+
result
|
28
|
+
end
|
29
|
+
|
30
|
+
def eql?(other)
|
31
|
+
other.instance_of?(RGBQuad) and
|
32
|
+
self[:red] == other[:red] and
|
33
|
+
self[:green] == other[:green] and
|
34
|
+
self[:blue] == other[:blue]
|
35
|
+
end
|
36
|
+
alias :== :eql?
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
"RGBQuad - Red: #{self[:red]}, Green: #{self[:green]}, Blue: #{self[:blue]}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/test/cookbook.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require './test_helper'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
def set_to_red(color)
|
7
|
+
color[:red] = 255
|
8
|
+
color[:green] = 0
|
9
|
+
color[:blue] = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
image = FreeImage::Bitmap.open('images/lena.png')
|
13
|
+
thumbnail = image.make_thumbnail(100)
|
14
|
+
|
15
|
+
# Make the bottom row red
|
16
|
+
scanline = thumbnail.scanline(0)
|
17
|
+
|
18
|
+
# Draw bottom border
|
19
|
+
(0..3).each do |index|
|
20
|
+
scanline = thumbnail.scanline(index)
|
21
|
+
scanline.each do |color|
|
22
|
+
set_to_red(color)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Draw top border
|
27
|
+
((thumbnail.height - 5)..(thumbnail.height - 1)).each do |index|
|
28
|
+
scanline = thumbnail.scanline(index)
|
29
|
+
scanline.each do |color|
|
30
|
+
set_to_red(color)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Draw left and right borders
|
35
|
+
(1..(thumbnail.height - 2)).each do |index|
|
36
|
+
scanline = thumbnail.scanline(index)
|
37
|
+
(0..4).each do |index|
|
38
|
+
set_to_red(scanline[index])
|
39
|
+
end
|
40
|
+
|
41
|
+
((thumbnail.width - 5)..(thumbnail.width - 1)).each do |index|
|
42
|
+
set_to_red(scanline[index])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
thumbnail.save("images/lena_thumbnail_border_scanline.png", :png)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
data/test/test_bitmap.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require './test_helper'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class BitmapTest < Test::Unit::TestCase
|
7
|
+
def test_bits
|
8
|
+
bytes = sample_image.bits
|
9
|
+
assert_equal(6466, bytes.size)
|
10
|
+
|
11
|
+
if defined?(Encoding)
|
12
|
+
assert_equal(Encoding::BINARY, bytes.encoding)
|
13
|
+
assert_equal(bytes.size, bytes.bytesize)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_open
|
18
|
+
bitmap = FreeImage::Bitmap.open('images/lena.png')
|
19
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_open_yield
|
23
|
+
result = FreeImage::Bitmap.open('images/lena.png') do |bitmap|
|
24
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
25
|
+
end
|
26
|
+
assert_equal(true, result)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_open_yield_error
|
30
|
+
assert_raise(ArgumentError) do
|
31
|
+
FreeImage::Bitmap.open('images/lena.png') do |bitmap|
|
32
|
+
raise(ArgumentError, "Let's mess things up")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_free
|
38
|
+
1000.times do
|
39
|
+
image = sample_image
|
40
|
+
image.free
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require './test_helper'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class ConverstionsTest < Test::Unit::TestCase
|
7
|
+
def test_convert_to_4bits
|
8
|
+
bitmap = sample_image.convert_to_4bits
|
9
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
10
|
+
assert_equal(4, bitmap.bits_per_pixel)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_convert_to_8bits
|
14
|
+
bitmap = sample_image.convert_to_8bits
|
15
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
16
|
+
assert_equal(8, bitmap.bits_per_pixel)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_convert_to_greyscale
|
20
|
+
bitmap = sample_image.convert_to_greyscale
|
21
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
22
|
+
assert_equal(8, bitmap.bits_per_pixel)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_convert_to_16bits_555
|
26
|
+
bitmap = sample_image.convert_to_16bits_555
|
27
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
28
|
+
assert_equal(16, bitmap.bits_per_pixel)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_convert_to_16bits_565
|
32
|
+
bitmap = sample_image.convert_to_16bits_565
|
33
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
34
|
+
assert_equal(16, bitmap.bits_per_pixel)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_convert_to_24bits
|
38
|
+
bitmap = sample_image.convert_to_24bits
|
39
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
40
|
+
assert_equal(24, bitmap.bits_per_pixel)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_convert_to_32bits
|
44
|
+
bitmap = sample_image.convert_to_32bits
|
45
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
46
|
+
assert_equal(32, bitmap.bits_per_pixel)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_convert_to_standard_type
|
50
|
+
bitmap = sample_image.convert_to_standard_type
|
51
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
52
|
+
assert_equal(8, bitmap.bits_per_pixel)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_convert_to_type
|
56
|
+
bitmap = sample_image.convert_to_type(:rgb16)
|
57
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
58
|
+
assert_equal(48, bitmap.bits_per_pixel)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_dither
|
62
|
+
bitmap = sample_image.dither(:bayer4x4)
|
63
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
64
|
+
assert_equal(1, bitmap.bits_per_pixel)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_threshold
|
68
|
+
bitmap = sample_image.threshold(7)
|
69
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
70
|
+
assert_equal(1, bitmap.bits_per_pixel)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_threshold_low
|
74
|
+
error = assert_raise(RangeError) do
|
75
|
+
sample_image.threshold(-1)
|
76
|
+
end
|
77
|
+
assert_equal("Value is out of range 0..255. Value: -1", error.message)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_threshold_hight
|
81
|
+
error = assert_raise(RangeError) do
|
82
|
+
sample_image.threshold(5555)
|
83
|
+
end
|
84
|
+
assert_equal("Value is out of range 0..255. Value: 5555", error.message)
|
85
|
+
end
|
86
|
+
end
|
data/test/test_file.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require './test_helper'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class FIFileTest < Test::Unit::TestCase
|
7
|
+
def file(image = 'sample.png')
|
8
|
+
path = image_path(image)
|
9
|
+
FreeImage::File.new(path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_format
|
13
|
+
assert_equal(:png, file.format)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_format_unknown
|
17
|
+
assert_equal(:unknown, file('not_an_image.txt').format)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_load
|
21
|
+
bitmap = file.open
|
22
|
+
assert_kind_of(FreeImage::Bitmap, bitmap)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_load_format
|
26
|
+
error = assert_raise(FreeImage::Error) do
|
27
|
+
file('not_an_image.txt').open
|
28
|
+
end
|
29
|
+
assert_equal('Cannot load :unknown image format', error.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_load_wrong_format
|
33
|
+
error = assert_raise(FreeImage::Error) do
|
34
|
+
file.open(:jpeg)
|
35
|
+
end
|
36
|
+
assert_equal("Not a JPEG file: starts with 0x89 0x50", error.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_save
|
40
|
+
tmp_file = Tempfile.new('test_free_image')
|
41
|
+
dst = FreeImage::File.new(tmp_file.path)
|
42
|
+
|
43
|
+
bitmap = file.open
|
44
|
+
result = bitmap.save(dst, :png)
|
45
|
+
assert(result)
|
46
|
+
assert(File.exists?(tmp_file))
|
47
|
+
ensure
|
48
|
+
tmp_file.close
|
49
|
+
tmp_file.unlink
|
50
|
+
end
|
51
|
+
end
|