free-image 0.6.2 → 0.7.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.
- checksums.yaml +7 -0
- data/HISTORY +30 -19
- data/LICENSE +20 -20
- data/README.rdoc +120 -120
- data/Rakefile +51 -47
- data/cookbook.rdoc +248 -237
- data/free-image.gemspec +30 -29
- data/lib/free-image.rb +1 -2
- data/lib/free-image/bitmap.rb +2 -2
- data/lib/free-image/enums/filters.rb +11 -11
- data/lib/free-image/errors.rb +43 -43
- data/lib/free-image/modules/conversions.rb +253 -253
- data/lib/free-image/modules/helper.rb +41 -41
- data/lib/free-image/modules/information.rb +20 -2
- data/lib/free-image/modules/modify.rb +299 -299
- data/lib/free-image/modules/pixels.rb +134 -134
- data/lib/free-image/modules/transforms.rb +90 -90
- data/lib/free-image/sources/abstract_source.rb +178 -178
- data/lib/free-image/sources/file.rb +114 -114
- data/lib/free-image/sources/io.rb +153 -153
- data/lib/free-image/sources/memory.rb +188 -188
- data/lib/free-image/types/boolean.rb +13 -13
- data/lib/free-image/types/ffi.rb +13 -13
- data/lib/free-image/types/info_header.rb +36 -0
- data/lib/free-image/types/rgb16.rb +31 -0
- data/test/cookbook.rb +45 -46
- data/test/images/sample_composite.png +0 -0
- data/test/images/test16.bmp +0 -0
- data/test/images/test16bf555.bmp +0 -0
- data/test/images/test16bf565.bmp +0 -0
- data/test/test_bitmap.rb +61 -63
- data/test/test_conversions.rb +85 -86
- data/test/test_file.rb +68 -69
- data/test/test_free_image.rb +14 -15
- data/test/test_helper.rb +14 -0
- data/test/test_information.rb +145 -117
- data/test/test_io.rb +73 -74
- data/test/test_memory.rb +83 -84
- data/test/test_modify.rb +75 -58
- data/test/test_palette.rb +44 -45
- data/test/test_pixels.rb +61 -62
- data/test/test_rgb_quad.rb +24 -25
- data/test/test_scanline.rb +64 -65
- data/test/test_suite.rb +12 -17
- data/test/test_transforms.rb +28 -29
- metadata +58 -31
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9ebfb83c042b8dc13d9284759db6aaafb51f706d
|
4
|
+
data.tar.gz: 94a96105ad584b3a77175d2a91d997316cc303bb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7e468e23c9918e0bebe109220e49c563277d700fc5a10d4e924a0042ae32900117e28817388dd95c48fb55659764749eb65ccc6ecaf567afa2f316d6c1380940
|
7
|
+
data.tar.gz: bfd559ca4e30420bf107711e3e96258e6287531407810786844ff31a00e76b1b84381eea461a71a33686b09f9e2d00cd19eaa2d633703cc69e35dfc7f86e284b
|
data/HISTORY
CHANGED
@@ -1,20 +1,31 @@
|
|
1
|
-
= Release History
|
2
|
-
|
3
|
-
== 0.
|
4
|
-
|
5
|
-
*
|
6
|
-
*
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
*
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
* Add
|
17
|
-
|
18
|
-
|
19
|
-
|
1
|
+
= Release History
|
2
|
+
|
3
|
+
== 0.7.0 / 2015-10-10
|
4
|
+
* Add test and example for compositing images (Charlie Savage)
|
5
|
+
* Specify freeimage version requirement (Charlie Savage)
|
6
|
+
* Fix up failing tests and test with FreeImage version 3.17.0 (Charlie Savage)
|
7
|
+
* Fix flip_vertical! to flip vertically, not horizontally (Chris Howlett)
|
8
|
+
* No rgb mask stored in modern FreeImage unless using BI_BITFIELDS in 16 bit BMP (Benjamin Armintor)
|
9
|
+
* Ruby object_id is a 32-bit value (Benjamin Armintor)
|
10
|
+
* Fix C type translation for bytes on osx/intel (Benjamin Armintor)
|
11
|
+
* Test suite clean up (Benjamin Armintor)
|
12
|
+
* Minor documentation updates (Charlie Savage)
|
13
|
+
|
14
|
+
== 0.6.2 / 2011-09-06
|
15
|
+
|
16
|
+
* Add null pointer checks when loading images
|
17
|
+
* Add null pointer check when creating a new image
|
18
|
+
|
19
|
+
== 0.6.1 / 2011-09-06
|
20
|
+
|
21
|
+
* Use release version on windows of FreeImage, not debug version.
|
22
|
+
|
23
|
+
== 0.6.0 / 2011-09-02
|
24
|
+
|
25
|
+
* Update documentation
|
26
|
+
* Add alternate library names
|
27
|
+
* Add support for blocks in all methods that return bitmaps
|
28
|
+
|
29
|
+
== 0.5.0 / 2011-08-28 Charlie Savage
|
30
|
+
|
20
31
|
* Initial Commit
|
data/LICENSE
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
Copyright (c) 2008-2011 Charlie Savage and contributors
|
2
|
-
Copyright (c) 2002-2007 Sean Chittenden and contributors
|
3
|
-
Copyright (c) 2001 Wai-Sun "Squidster" Chia
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
-
this software and associated documentation files (the "Software"), to deal in
|
7
|
-
the Software without restriction, including without limitation the rights to
|
8
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
9
|
-
of the Software, and to permit persons to whom the Software is furnished to do
|
10
|
-
so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
1
|
+
Copyright (c) 2008-2011 Charlie Savage and contributors
|
2
|
+
Copyright (c) 2002-2007 Sean Chittenden and contributors
|
3
|
+
Copyright (c) 2001 Wai-Sun "Squidster" Chia
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
10
|
+
so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
SOFTWARE.
|
data/README.rdoc
CHANGED
@@ -1,120 +1,120 @@
|
|
1
|
-
= FreeImage Ruby Bindings
|
2
|
-
|
3
|
-
== Overview
|
4
|
-
The free-image gem provides Ruby language bindings for the
|
5
|
-
FreeImage[http://freeimage.sourceforge.net/] library. It is free software,
|
6
|
-
released under the MIT License.
|
7
|
-
|
8
|
-
FreeImage is an light-weight, open source image manipulation library that
|
9
|
-
supports many popular graphics image {formats}[rdoc-ref:FreeImage.formats]
|
10
|
-
such as PNG, JPEG, GIF, BMP, and TIFF.
|
11
|
-
|
12
|
-
We think FreeImage is a great library for applications that need to read, write,
|
13
|
-
create and modify images and thumbnails because:
|
14
|
-
|
15
|
-
* Its easy to use
|
16
|
-
* Its supports almost all popular image formats
|
17
|
-
* Its a light-weight alternative to larger libraries such as ImageMagick,
|
18
|
-
supporting basic manipulation functions but not advanced functionality
|
19
|
-
* Its cross-platform
|
20
|
-
* The ruby bindings are implemented using FFI, so work across all Ruby
|
21
|
-
implementations and do not have to be compiled
|
22
|
-
* Its much more comprehensive than ImageScience
|
23
|
-
* Has comprehensive documentation
|
24
|
-
|
25
|
-
Note that FreeImage is not the right library for you if you need:
|
26
|
-
* Advanced image processing operations such as convolution and transforms
|
27
|
-
* Bitmap drawing
|
28
|
-
* Vector graphics
|
29
|
-
|
30
|
-
== Installation
|
31
|
-
free-image requires Ruby 1.8.7 or higher. The easiest way to install
|
32
|
-
free-image is via Ruby Gems. To install:
|
33
|
-
|
34
|
-
gem install free-image
|
35
|
-
|
36
|
-
== Getting Started
|
37
|
-
Getting started is easy - first work through the examples in the cookbook[
|
38
|
-
Once you've done that, the refer to rdocs for extensive documentation.
|
39
|
-
|
40
|
-
== Memory Management
|
41
|
-
Opening and working with images consumes some memory. Generally you won't have to
|
42
|
-
worry about this. When an image goes out of scope, it will be garbage collected
|
43
|
-
and the underlying image memory will be freed.
|
44
|
-
|
45
|
-
Having said that, \FreeImage also lets you control when the memory is freed.
|
46
|
-
Any method that creates a new image also takes a block. When the block finishes,
|
47
|
-
the underlying image memory is freed. This works the same way as the File.open
|
48
|
-
method. For example:
|
49
|
-
|
50
|
-
FreeImage::Bitmap.open('images/lena.png') do |image|
|
51
|
-
thumbnail = image.make_thumbail do |thumbail|
|
52
|
-
thumbnail.save('images/thumbnail.png', :png)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
When the inner block finishes the thumbnail image is freed and when the outer
|
57
|
-
block finished the lena image is freed.
|
58
|
-
|
59
|
-
If you need even more control, you can use FreeImage::Bitmap#free which frees
|
60
|
-
the underlying image. Be careful though - once the image is freed further usage
|
61
|
-
of it will result in a segmentation fault.
|
62
|
-
|
63
|
-
== Implementation Status
|
64
|
-
The FreeImage API is divided into multiple parts. As summarized below, the Ruby ffi
|
65
|
-
bindings currently implement a subset of the available api. Patches are welcome to
|
66
|
-
extend the coverage.
|
67
|
-
|
68
|
-
=== Bitmap functions
|
69
|
-
* General - FreeImage::Bitmap
|
70
|
-
* Bitmap management - FreeImage::Bitmap
|
71
|
-
* Bitmap information - FreeImage::Information, FreeImage::Color::Palette
|
72
|
-
* Filetype - FreeImage::File, FreeImage::IO, FreeImage::Memory
|
73
|
-
* Pixel access - FreeImage::Pixel
|
74
|
-
* Conversion - FreeImage::Conversions
|
75
|
-
* Tone mapping - Not Implemented
|
76
|
-
* ICC profile - FreeImage::ICC
|
77
|
-
* Plugin - Not Implemented
|
78
|
-
* Multipage - Not Implemented
|
79
|
-
* Memory I/O streams - FreeImage::MemoryStream
|
80
|
-
* Compression - Not Implemented
|
81
|
-
* Helper functions - FreeImage::Helper
|
82
|
-
|
83
|
-
=== Metadata Functions
|
84
|
-
* Introduction - Not Implemented
|
85
|
-
* Tag creation and destruction - Not Implemented
|
86
|
-
* Tag accessors - Not Implemented
|
87
|
-
* Metadata iterator - Not Implemented
|
88
|
-
* Metadata accessors - Not Implemented
|
89
|
-
* Metadata helper functions - Not Implemented
|
90
|
-
|
91
|
-
=== Toolkit Functions
|
92
|
-
* Rotation and flipping - FreeImage::Transforms
|
93
|
-
* Upsampling / downsampling - FreeImage::Modify
|
94
|
-
* Color manipulation - Not Implemented
|
95
|
-
* Channel processing - Not Implemented
|
96
|
-
* Copy / Paste / Composite routines - FreeImage::Modify
|
97
|
-
* Background filling - FreeImage::Modify
|
98
|
-
* Miscellaneous algorithms - FreeImage::Helper
|
99
|
-
|
100
|
-
== Documentation
|
101
|
-
Documentation is available via rdoc, and is installed automatically with the
|
102
|
-
gem. Note that much of the documentation is directly copied from
|
103
|
-
the FreeImage API documentation available
|
104
|
-
here[http://downloads.sourceforge.net/freeimage/FreeImage3151.pdf].
|
105
|
-
|
106
|
-
free-image's online documentation is generated using Hanna. To generate
|
107
|
-
documentation from source:
|
108
|
-
|
109
|
-
gem install hanna-nouveau
|
110
|
-
rake rdoc
|
111
|
-
- or -
|
112
|
-
rdoc -o doc/rdoc -f hanna -m "README.rdoc" lib/**/*.rb README.rdoc
|
113
|
-
|
114
|
-
|
115
|
-
== Support
|
116
|
-
|
117
|
-
If you have any questions about using free-image, please ?
|
118
|
-
|
119
|
-
== License
|
120
|
-
See LICENSE for license information.
|
1
|
+
= FreeImage Ruby Bindings
|
2
|
+
|
3
|
+
== Overview
|
4
|
+
The free-image gem provides Ruby language bindings for the
|
5
|
+
FreeImage[http://freeimage.sourceforge.net/] library. It is free software,
|
6
|
+
released under the MIT License.
|
7
|
+
|
8
|
+
FreeImage is an light-weight, open source image manipulation library that
|
9
|
+
supports many popular graphics image {formats}[rdoc-ref:FreeImage.formats]
|
10
|
+
such as PNG, JPEG, GIF, BMP, and TIFF.
|
11
|
+
|
12
|
+
We think FreeImage is a great library for applications that need to read, write,
|
13
|
+
create and modify images and thumbnails because:
|
14
|
+
|
15
|
+
* Its easy to use
|
16
|
+
* Its supports almost all popular image formats
|
17
|
+
* Its a light-weight alternative to larger libraries such as ImageMagick,
|
18
|
+
supporting basic manipulation functions but not advanced functionality
|
19
|
+
* Its cross-platform
|
20
|
+
* The ruby bindings are implemented using FFI, so work across all Ruby
|
21
|
+
implementations and do not have to be compiled
|
22
|
+
* Its much more comprehensive than ImageScience
|
23
|
+
* Has comprehensive documentation
|
24
|
+
|
25
|
+
Note that FreeImage is not the right library for you if you need:
|
26
|
+
* Advanced image processing operations such as convolution and transforms
|
27
|
+
* Bitmap drawing
|
28
|
+
* Vector graphics
|
29
|
+
|
30
|
+
== Installation
|
31
|
+
free-image requires FreeImage version 3.10 or higher and Ruby 1.8.7 or higher. The easiest way to install
|
32
|
+
free-image is via Ruby Gems. To install:
|
33
|
+
|
34
|
+
gem install free-image
|
35
|
+
|
36
|
+
== Getting Started
|
37
|
+
Getting started is easy - first work through the examples in the {cookbook}[http://cfis.github.io/free-image-ruby/].
|
38
|
+
Once you've done that, the refer to rdocs for extensive documentation.
|
39
|
+
|
40
|
+
== Memory Management
|
41
|
+
Opening and working with images consumes some memory. Generally you won't have to
|
42
|
+
worry about this. When an image goes out of scope, it will be garbage collected
|
43
|
+
and the underlying image memory will be freed.
|
44
|
+
|
45
|
+
Having said that, \FreeImage also lets you control when the memory is freed.
|
46
|
+
Any method that creates a new image also takes a block. When the block finishes,
|
47
|
+
the underlying image memory is freed. This works the same way as the File.open
|
48
|
+
method. For example:
|
49
|
+
|
50
|
+
FreeImage::Bitmap.open('images/lena.png') do |image|
|
51
|
+
thumbnail = image.make_thumbail do |thumbail|
|
52
|
+
thumbnail.save('images/thumbnail.png', :png)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
When the inner block finishes the thumbnail image is freed and when the outer
|
57
|
+
block finished the lena image is freed.
|
58
|
+
|
59
|
+
If you need even more control, you can use FreeImage::Bitmap#free which frees
|
60
|
+
the underlying image. Be careful though - once the image is freed further usage
|
61
|
+
of it will result in a segmentation fault.
|
62
|
+
|
63
|
+
== Implementation Status
|
64
|
+
The FreeImage API is divided into multiple parts. As summarized below, the Ruby ffi
|
65
|
+
bindings currently implement a subset of the available api. Patches are welcome to
|
66
|
+
extend the coverage.
|
67
|
+
|
68
|
+
=== Bitmap functions
|
69
|
+
* General - FreeImage::Bitmap
|
70
|
+
* Bitmap management - FreeImage::Bitmap
|
71
|
+
* Bitmap information - FreeImage::Information, FreeImage::Color::Palette
|
72
|
+
* Filetype - FreeImage::File, FreeImage::IO, FreeImage::Memory
|
73
|
+
* Pixel access - FreeImage::Pixel
|
74
|
+
* Conversion - FreeImage::Conversions
|
75
|
+
* Tone mapping - Not Implemented
|
76
|
+
* ICC profile - FreeImage::ICC
|
77
|
+
* Plugin - Not Implemented
|
78
|
+
* Multipage - Not Implemented
|
79
|
+
* Memory I/O streams - FreeImage::MemoryStream
|
80
|
+
* Compression - Not Implemented
|
81
|
+
* Helper functions - FreeImage::Helper
|
82
|
+
|
83
|
+
=== Metadata Functions
|
84
|
+
* Introduction - Not Implemented
|
85
|
+
* Tag creation and destruction - Not Implemented
|
86
|
+
* Tag accessors - Not Implemented
|
87
|
+
* Metadata iterator - Not Implemented
|
88
|
+
* Metadata accessors - Not Implemented
|
89
|
+
* Metadata helper functions - Not Implemented
|
90
|
+
|
91
|
+
=== Toolkit Functions
|
92
|
+
* Rotation and flipping - FreeImage::Transforms
|
93
|
+
* Upsampling / downsampling - FreeImage::Modify
|
94
|
+
* Color manipulation - Not Implemented
|
95
|
+
* Channel processing - Not Implemented
|
96
|
+
* Copy / Paste / Composite routines - FreeImage::Modify
|
97
|
+
* Background filling - FreeImage::Modify
|
98
|
+
* Miscellaneous algorithms - FreeImage::Helper
|
99
|
+
|
100
|
+
== Documentation
|
101
|
+
Documentation is available via rdoc, and is installed automatically with the
|
102
|
+
gem. Note that much of the documentation is directly copied from
|
103
|
+
the FreeImage API documentation available
|
104
|
+
here[http://downloads.sourceforge.net/freeimage/FreeImage3151.pdf].
|
105
|
+
|
106
|
+
free-image's online documentation is generated using Hanna. To generate
|
107
|
+
documentation from source:
|
108
|
+
|
109
|
+
gem install hanna-nouveau
|
110
|
+
rake rdoc
|
111
|
+
- or -
|
112
|
+
rdoc -o doc/rdoc -f hanna -m "README.rdoc" lib/**/*.rb README.rdoc
|
113
|
+
|
114
|
+
|
115
|
+
== Support
|
116
|
+
|
117
|
+
If you have any questions about using free-image, please ?
|
118
|
+
|
119
|
+
== License
|
120
|
+
See LICENSE for license information.
|
data/Rakefile
CHANGED
@@ -1,47 +1,51 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
# !/usr/bin/env ruby
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "rake/testtask"
|
6
|
-
require "rubygems/package_task"
|
7
|
-
require "rdoc/task"
|
8
|
-
require "fileutils"
|
9
|
-
|
10
|
-
GEM_NAME = "free-image"
|
11
|
-
|
12
|
-
# Read the spec file
|
13
|
-
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
14
|
-
|
15
|
-
# Setup generic gem
|
16
|
-
Gem::PackageTask.new(spec) do |pkg|
|
17
|
-
pkg.package_dir = 'pkg'
|
18
|
-
pkg.need_tar = false
|
19
|
-
end
|
20
|
-
|
21
|
-
# RDoc Task
|
22
|
-
desc "Generate rdoc documentation"
|
23
|
-
RDoc::Task.new("rdoc") do |rdoc|
|
24
|
-
rdoc.rdoc_dir = 'doc'
|
25
|
-
rdoc.title = "FreeImage"
|
26
|
-
# Show source inline with line numbers
|
27
|
-
rdoc.options << "--line-numbers"
|
28
|
-
# Use Hanna - this only works with RDoc 3.1 or greater
|
29
|
-
rdoc.generator = 'hanna'
|
30
|
-
# Make the readme file the start page for the generated html
|
31
|
-
rdoc.main = 'cookbook.rdoc'
|
32
|
-
rdoc.rdoc_files = FileList['HISTORY',
|
33
|
-
'LICENSE',
|
34
|
-
'*.rdoc',
|
35
|
-
'lib/**/*.rb']
|
36
|
-
end
|
37
|
-
|
38
|
-
desc "Setup Cookbook"
|
39
|
-
task :cookbook => :rdoc do
|
40
|
-
FileUtils.cp_r("test/images", "doc/cookbook")
|
41
|
-
end
|
42
|
-
|
43
|
-
# Test Task
|
44
|
-
Rake::TestTask.new do |t|
|
45
|
-
t.
|
46
|
-
t.
|
47
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
# !/usr/bin/env ruby
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "rake/testtask"
|
6
|
+
require "rubygems/package_task"
|
7
|
+
require "rdoc/task"
|
8
|
+
require "fileutils"
|
9
|
+
|
10
|
+
GEM_NAME = "free-image"
|
11
|
+
|
12
|
+
# Read the spec file
|
13
|
+
spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
|
14
|
+
|
15
|
+
# Setup generic gem
|
16
|
+
Gem::PackageTask.new(spec) do |pkg|
|
17
|
+
pkg.package_dir = 'pkg'
|
18
|
+
pkg.need_tar = false
|
19
|
+
end
|
20
|
+
|
21
|
+
# RDoc Task
|
22
|
+
desc "Generate rdoc documentation"
|
23
|
+
RDoc::Task.new("rdoc") do |rdoc|
|
24
|
+
rdoc.rdoc_dir = 'doc'
|
25
|
+
rdoc.title = "FreeImage"
|
26
|
+
# Show source inline with line numbers
|
27
|
+
rdoc.options << "--line-numbers"
|
28
|
+
# Use Hanna - this only works with RDoc 3.1 or greater
|
29
|
+
rdoc.generator = 'hanna'
|
30
|
+
# Make the readme file the start page for the generated html
|
31
|
+
rdoc.main = 'cookbook.rdoc'
|
32
|
+
rdoc.rdoc_files = FileList['HISTORY',
|
33
|
+
'LICENSE',
|
34
|
+
'*.rdoc',
|
35
|
+
'lib/**/*.rb']
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Setup Cookbook"
|
39
|
+
task :cookbook => :rdoc do
|
40
|
+
FileUtils.cp_r("test/images", "doc/cookbook")
|
41
|
+
end
|
42
|
+
|
43
|
+
# Test Task
|
44
|
+
Rake::TestTask.new do |t|
|
45
|
+
t.pattern = 'test/**/test_*.rb'
|
46
|
+
t.libs << "lib"
|
47
|
+
t.libs << "test"
|
48
|
+
t.verbose = true
|
49
|
+
end
|
50
|
+
|
51
|
+
task default: :test
|
data/cookbook.rdoc
CHANGED
@@ -1,238 +1,249 @@
|
|
1
|
-
= \Getting Started With \FreeImage
|
2
|
-
Below are various recipes to get you up and running with \FreeImage as quickly
|
3
|
-
as possible. The example images tcan be found in the
|
4
|
-
test/images directory. For more general information about \FreeImage, including
|
5
|
-
installation instructions, please refer to README.rdoc.
|
6
|
-
|
7
|
-
== Loading An Image
|
8
|
-
The first step in using \FreeImage is to load an image. \FreeImage can load
|
9
|
-
images from files[rdoc-ref::FreeImage::File], strings[rdoc-ref::FreeImage::Memory]
|
10
|
-
or IO[rdoc-ref::FreeImage::IO] streams. The simplest way to do this is
|
11
|
-
via the FreeImage::Bitmap.open method:
|
12
|
-
|
13
|
-
image = FreeImage::Bitmap.open('images/lena.tiff')
|
14
|
-
image = FreeImage::Bitmap.open(io_object)
|
15
|
-
image = FreeImage::Bitmap.open(FreeImage::Memory.new(string))
|
16
|
-
|
17
|
-
The open method also takes two additional optional parameters, format and flags,
|
18
|
-
that provide greater control over opening images if needed.
|
19
|
-
|
20
|
-
The open method works similary to File.open, meaning you can also pass it a block.
|
21
|
-
|
22
|
-
FreeImage::Bitmap.open('images/lena.png') do |image|
|
23
|
-
... do some stuff..
|
24
|
-
end
|
25
|
-
|
26
|
-
Once the block completes, the image will be automatically freed for you. If you don't
|
27
|
-
pass block, then the image will be freed by Ruby's Garbage Collector once it goes out
|
28
|
-
of scope. For more information about memory management, refer to
|
29
|
-
the readme [rdoc-ref:README.rdoc].
|
30
|
-
|
31
|
-
Image[link:cookbook/lena.png]
|
32
|
-
|
33
|
-
== Saving An Image
|
34
|
-
Now let's say you want to save the image to :png format. This is done
|
35
|
-
via the FreeImage::Bitmap.save method. The save method takes a destination,
|
36
|
-
which can be a file[rdoc-ref::FreeImage::File], string[rdoc-ref::FreeImage::Memory]
|
37
|
-
or IO[rdoc-ref::FreeImage::IO] stream, and an image format.
|
38
|
-
|
39
|
-
image.save('images/lena.png', :png)
|
40
|
-
|
41
|
-
== Creating a Thumbnail
|
42
|
-
Next, let's assume our application needs to show a list of thumbnails for the images
|
43
|
-
it stores. This can be done using the make_thumbnail[rdoc-ref:FreeImage::Modify.make_thumbnail]
|
44
|
-
method in the Modify[rdoc-ref:FreeImage::Modify] module.
|
45
|
-
|
46
|
-
thumbnail = image.make_thumbnail(100)
|
47
|
-
thumbnail.save('images/lena_thumbnail.png', :png)
|
48
|
-
|
49
|
-
Thumbnail[link:cookbook/lena_thumbnail.png]
|
50
|
-
|
51
|
-
== Putting a Border Around a Thumbnail
|
52
|
-
Once we have created a thumbnail, let's outline it with a red border. There
|
53
|
-
are various approaches to do doing this. In the first approach, we'll use
|
54
|
-
the enlarge_canvas[FreeImage::Modify.enlarge_canvas] method.
|
55
|
-
|
56
|
-
# Border size
|
57
|
-
border = 4
|
58
|
-
|
59
|
-
# Specify the color as red
|
60
|
-
color = FreeImage::RGBQuad.create(255, 0, 0)
|
61
|
-
|
62
|
-
# Add 4 pixel red border around the thumbnail
|
63
|
-
thumbnail_border = thumbnail.enlarge_canvas(border, border, border, border, color)
|
64
|
-
thumbnail_border.save('images/lena_thumbnail_border_1.png', :png)
|
65
|
-
|
66
|
-
ThumbnailBorderEnlarge[link:cookbook/lena_thumbnail_border_enlarge.png]
|
67
|
-
|
68
|
-
In the second approach, let's create a image with a red background
|
69
|
-
and then paste it on top of our thumbnail:
|
70
|
-
|
71
|
-
# Create a red image that is the same size as the thumbnail
|
72
|
-
red_image = FreeImage::Bitmap.create(thumbnail.width, thumbnail.height, thumbnail.bits_per_pixel)
|
73
|
-
red_image_new.fill_background(color)
|
74
|
-
|
75
|
-
# Now copy a subimage from the thumbnail that is 2 borders less wide and tall
|
76
|
-
subimage = thumbnail.copy(border, border, thumbnail.width - border, thumbnail.height - border)
|
77
|
-
|
78
|
-
# Now paste the subimage into the red image. Specify an alpha over 255
|
79
|
-
# to disable alpha blending
|
80
|
-
red_image.paste(subimage, border, border, 300)
|
81
|
-
red_image.save('images/test1.png', :png)
|
82
|
-
thumbnail_border.save('images/lena_thumbnail_border_2.png', :png)
|
83
|
-
|
84
|
-
ThumbnailBorderPaste[link:cookbook/lena_thumbnail_border_paste.png]
|
85
|
-
|
86
|
-
== Resampling An Image
|
87
|
-
If you need additional control over how an image is resampled, use the
|
88
|
-
FreeImage::Bitmap#rescale method, which lets you specify a filtering
|
89
|
-
algorithm. To see how each filter works, let's scale up the thumbnail
|
90
|
-
by 400%.
|
91
|
-
|
92
|
-
thumbnail = FreeImage::Bitmap.open('images/lena_thumbnail.png')
|
93
|
-
|
94
|
-
FreeImage.enum_type(:filter).symbols.each do |filter|
|
95
|
-
rescaled = thumbnail.rescale(thumbnail.width * 4, thumbnail.height * 4, filter)
|
96
|
-
rescaled.save("images/lena_rescale_#{filter.to_s}.png", :png)
|
97
|
-
end
|
98
|
-
|
99
|
-
RescaleBox[link:cookbook/lena_rescale_box.png]
|
100
|
-
RescaleBicubic[link:cookbook/lena_rescale_bicubic.png]
|
101
|
-
RescaleBilinear[link:cookbook/lena_rescale_bilinear.png]
|
102
|
-
RescaleBspline[link:cookbook/lena_rescale_bspline.png]
|
103
|
-
RescaleCatmullrom[link:cookbook/lena_rescale_catmullrom.png]
|
104
|
-
RescaleLanczos3[link:cookbook/lena_rescale_lanczos3.png]
|
105
|
-
|
106
|
-
== Flipping An Image
|
107
|
-
The Transform modules lets you flip or rotate an image. Let's say you want to
|
108
|
-
flip your image horizontally:
|
109
|
-
|
110
|
-
image.flip_horizontal
|
111
|
-
image.save('images/lena_flipped.png', :png)
|
112
|
-
|
113
|
-
Thumbnail[link:cookbook/lena_flipped.png]
|
114
|
-
|
115
|
-
== Rotating An Image
|
116
|
-
Next, let's rotate an image. Two methods are provide, FreeImage::Bitmap#rotate and
|
117
|
-
FreeImage::Bitmap#rotate_ex. The #rotate method is simpler to use:
|
118
|
-
|
119
|
-
image = FreeImage::Bitmap.open('images/lena.png', :png)
|
120
|
-
|
121
|
-
# Rotate the image 45 degrees using white as the background fill color
|
122
|
-
color = FreeImage::RGBQuad.create(255, 255, 255, 0)
|
123
|
-
rotated = image.rotate(45, color)
|
124
|
-
rotated.save("images/lena_rotate_45.png", :png)
|
125
|
-
|
126
|
-
Thumbnail[link:cookbook/lena_rotate_45.png]
|
127
|
-
|
128
|
-
Notice that the image size and geometry has changed? Thus, the #rotate
|
129
|
-
function is best for rotating and image 90, 180 or 270 degrees.
|
130
|
-
|
131
|
-
Let's now rotate the image using the #rotate_ex method while using a mask:
|
132
|
-
|
133
|
-
rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, true)
|
134
|
-
rotated.save("images/lena_rotate_ex_45_masked.png", :png)
|
135
|
-
|
136
|
-
And now let's rotate the image without a mask, so data is filled in using
|
137
|
-
a mirroring algorithm:
|
138
|
-
|
139
|
-
rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, false)
|
140
|
-
rotated.save("images/lena_rotate_ex_45_mirrored.png", :png)
|
141
|
-
|
142
|
-
Thumbnail[link:cookbook/lena_rotate_ex_45_masked.png]
|
143
|
-
Thumbnail[link:cookbook/lena_rotate_ex_45_mirrored.png]
|
144
|
-
|
145
|
-
Last, lets rotate the image around the top left corner:
|
146
|
-
|
147
|
-
rotated = image.rotate_ex(45, 0, 0, 0, 0, true)
|
148
|
-
rotated.save("images/lena_rotate_ex_45_top_left.png", :png)
|
149
|
-
|
150
|
-
Thumbnail[link:cookbook/lena_rotate_ex_45_top_left.png]
|
151
|
-
|
152
|
-
== Compositing An Image
|
153
|
-
\FreeImage also lets you composite an image with a background color or another image.
|
154
|
-
Here is an example of compositing an image with the color green.
|
155
|
-
|
156
|
-
image = FreeImage::Bitmap.open('images/sample.png')
|
157
|
-
color = FreeImage::RGBQuad.create(0, 255, 0, 0)
|
158
|
-
composite = image.composite_with_color(color)
|
159
|
-
composite.save("images/sample_composite_color.png", :png)
|
160
|
-
|
161
|
-
Sample[link:cookbook/sample.png]
|
162
|
-
SampleCompositeColor[link:cookbook/sample_composite_color.png]
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
image.
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
#
|
207
|
-
(
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
1
|
+
= \Getting Started With \FreeImage
|
2
|
+
Below are various recipes to get you up and running with \FreeImage as quickly
|
3
|
+
as possible. The example images tcan be found in the
|
4
|
+
test/images directory. For more general information about \FreeImage, including
|
5
|
+
installation instructions, please refer to README.rdoc.
|
6
|
+
|
7
|
+
== Loading An Image
|
8
|
+
The first step in using \FreeImage is to load an image. \FreeImage can load
|
9
|
+
images from files[rdoc-ref::FreeImage::File], strings[rdoc-ref::FreeImage::Memory]
|
10
|
+
or IO[rdoc-ref::FreeImage::IO] streams. The simplest way to do this is
|
11
|
+
via the FreeImage::Bitmap.open method:
|
12
|
+
|
13
|
+
image = FreeImage::Bitmap.open('images/lena.tiff')
|
14
|
+
image = FreeImage::Bitmap.open(io_object)
|
15
|
+
image = FreeImage::Bitmap.open(FreeImage::Memory.new(string))
|
16
|
+
|
17
|
+
The open method also takes two additional optional parameters, format and flags,
|
18
|
+
that provide greater control over opening images if needed.
|
19
|
+
|
20
|
+
The open method works similary to File.open, meaning you can also pass it a block.
|
21
|
+
|
22
|
+
FreeImage::Bitmap.open('images/lena.png') do |image|
|
23
|
+
... do some stuff..
|
24
|
+
end
|
25
|
+
|
26
|
+
Once the block completes, the image will be automatically freed for you. If you don't
|
27
|
+
pass block, then the image will be freed by Ruby's Garbage Collector once it goes out
|
28
|
+
of scope. For more information about memory management, refer to
|
29
|
+
the readme [rdoc-ref:README.rdoc].
|
30
|
+
|
31
|
+
Image[link:cookbook/lena.png]
|
32
|
+
|
33
|
+
== Saving An Image
|
34
|
+
Now let's say you want to save the image to :png format. This is done
|
35
|
+
via the FreeImage::Bitmap.save method. The save method takes a destination,
|
36
|
+
which can be a file[rdoc-ref::FreeImage::File], string[rdoc-ref::FreeImage::Memory]
|
37
|
+
or IO[rdoc-ref::FreeImage::IO] stream, and an image format.
|
38
|
+
|
39
|
+
image.save('images/lena.png', :png)
|
40
|
+
|
41
|
+
== Creating a Thumbnail
|
42
|
+
Next, let's assume our application needs to show a list of thumbnails for the images
|
43
|
+
it stores. This can be done using the make_thumbnail[rdoc-ref:FreeImage::Modify.make_thumbnail]
|
44
|
+
method in the Modify[rdoc-ref:FreeImage::Modify] module.
|
45
|
+
|
46
|
+
thumbnail = image.make_thumbnail(100)
|
47
|
+
thumbnail.save('images/lena_thumbnail.png', :png)
|
48
|
+
|
49
|
+
Thumbnail[link:cookbook/lena_thumbnail.png]
|
50
|
+
|
51
|
+
== Putting a Border Around a Thumbnail
|
52
|
+
Once we have created a thumbnail, let's outline it with a red border. There
|
53
|
+
are various approaches to do doing this. In the first approach, we'll use
|
54
|
+
the enlarge_canvas[FreeImage::Modify.enlarge_canvas] method.
|
55
|
+
|
56
|
+
# Border size
|
57
|
+
border = 4
|
58
|
+
|
59
|
+
# Specify the color as red
|
60
|
+
color = FreeImage::RGBQuad.create(255, 0, 0)
|
61
|
+
|
62
|
+
# Add 4 pixel red border around the thumbnail
|
63
|
+
thumbnail_border = thumbnail.enlarge_canvas(border, border, border, border, color)
|
64
|
+
thumbnail_border.save('images/lena_thumbnail_border_1.png', :png)
|
65
|
+
|
66
|
+
ThumbnailBorderEnlarge[link:cookbook/lena_thumbnail_border_enlarge.png]
|
67
|
+
|
68
|
+
In the second approach, let's create a image with a red background
|
69
|
+
and then paste it on top of our thumbnail:
|
70
|
+
|
71
|
+
# Create a red image that is the same size as the thumbnail
|
72
|
+
red_image = FreeImage::Bitmap.create(thumbnail.width, thumbnail.height, thumbnail.bits_per_pixel)
|
73
|
+
red_image_new.fill_background(color)
|
74
|
+
|
75
|
+
# Now copy a subimage from the thumbnail that is 2 borders less wide and tall
|
76
|
+
subimage = thumbnail.copy(border, border, thumbnail.width - border, thumbnail.height - border)
|
77
|
+
|
78
|
+
# Now paste the subimage into the red image. Specify an alpha over 255
|
79
|
+
# to disable alpha blending
|
80
|
+
red_image.paste(subimage, border, border, 300)
|
81
|
+
red_image.save('images/test1.png', :png)
|
82
|
+
thumbnail_border.save('images/lena_thumbnail_border_2.png', :png)
|
83
|
+
|
84
|
+
ThumbnailBorderPaste[link:cookbook/lena_thumbnail_border_paste.png]
|
85
|
+
|
86
|
+
== Resampling An Image
|
87
|
+
If you need additional control over how an image is resampled, use the
|
88
|
+
FreeImage::Bitmap#rescale method, which lets you specify a filtering
|
89
|
+
algorithm. To see how each filter works, let's scale up the thumbnail
|
90
|
+
by 400%.
|
91
|
+
|
92
|
+
thumbnail = FreeImage::Bitmap.open('images/lena_thumbnail.png')
|
93
|
+
|
94
|
+
FreeImage.enum_type(:filter).symbols.each do |filter|
|
95
|
+
rescaled = thumbnail.rescale(thumbnail.width * 4, thumbnail.height * 4, filter)
|
96
|
+
rescaled.save("images/lena_rescale_#{filter.to_s}.png", :png)
|
97
|
+
end
|
98
|
+
|
99
|
+
RescaleBox[link:cookbook/lena_rescale_box.png]
|
100
|
+
RescaleBicubic[link:cookbook/lena_rescale_bicubic.png]
|
101
|
+
RescaleBilinear[link:cookbook/lena_rescale_bilinear.png]
|
102
|
+
RescaleBspline[link:cookbook/lena_rescale_bspline.png]
|
103
|
+
RescaleCatmullrom[link:cookbook/lena_rescale_catmullrom.png]
|
104
|
+
RescaleLanczos3[link:cookbook/lena_rescale_lanczos3.png]
|
105
|
+
|
106
|
+
== Flipping An Image
|
107
|
+
The Transform modules lets you flip or rotate an image. Let's say you want to
|
108
|
+
flip your image horizontally:
|
109
|
+
|
110
|
+
image.flip_horizontal
|
111
|
+
image.save('images/lena_flipped.png', :png)
|
112
|
+
|
113
|
+
Thumbnail[link:cookbook/lena_flipped.png]
|
114
|
+
|
115
|
+
== Rotating An Image
|
116
|
+
Next, let's rotate an image. Two methods are provide, FreeImage::Bitmap#rotate and
|
117
|
+
FreeImage::Bitmap#rotate_ex. The #rotate method is simpler to use:
|
118
|
+
|
119
|
+
image = FreeImage::Bitmap.open('images/lena.png', :png)
|
120
|
+
|
121
|
+
# Rotate the image 45 degrees using white as the background fill color
|
122
|
+
color = FreeImage::RGBQuad.create(255, 255, 255, 0)
|
123
|
+
rotated = image.rotate(45, color)
|
124
|
+
rotated.save("images/lena_rotate_45.png", :png)
|
125
|
+
|
126
|
+
Thumbnail[link:cookbook/lena_rotate_45.png]
|
127
|
+
|
128
|
+
Notice that the image size and geometry has changed? Thus, the #rotate
|
129
|
+
function is best for rotating and image 90, 180 or 270 degrees.
|
130
|
+
|
131
|
+
Let's now rotate the image using the #rotate_ex method while using a mask:
|
132
|
+
|
133
|
+
rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, true)
|
134
|
+
rotated.save("images/lena_rotate_ex_45_masked.png", :png)
|
135
|
+
|
136
|
+
And now let's rotate the image without a mask, so data is filled in using
|
137
|
+
a mirroring algorithm:
|
138
|
+
|
139
|
+
rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, false)
|
140
|
+
rotated.save("images/lena_rotate_ex_45_mirrored.png", :png)
|
141
|
+
|
142
|
+
Thumbnail[link:cookbook/lena_rotate_ex_45_masked.png]
|
143
|
+
Thumbnail[link:cookbook/lena_rotate_ex_45_mirrored.png]
|
144
|
+
|
145
|
+
Last, lets rotate the image around the top left corner:
|
146
|
+
|
147
|
+
rotated = image.rotate_ex(45, 0, 0, 0, 0, true)
|
148
|
+
rotated.save("images/lena_rotate_ex_45_top_left.png", :png)
|
149
|
+
|
150
|
+
Thumbnail[link:cookbook/lena_rotate_ex_45_top_left.png]
|
151
|
+
|
152
|
+
== Compositing An Image
|
153
|
+
\FreeImage also lets you composite an image with a background color or another image.
|
154
|
+
Here is an example of compositing an image with the color green.
|
155
|
+
|
156
|
+
image = FreeImage::Bitmap.open('images/sample.png')
|
157
|
+
color = FreeImage::RGBQuad.create(0, 255, 0, 0)
|
158
|
+
composite = image.composite_with_color(color)
|
159
|
+
composite.save("images/sample_composite_color.png", :png)
|
160
|
+
|
161
|
+
Sample[link:cookbook/sample.png]
|
162
|
+
SampleCompositeColor[link:cookbook/sample_composite_color.png]
|
163
|
+
|
164
|
+
And here is an example of compositing two images together:
|
165
|
+
|
166
|
+
image = FreeImage::Bitmap.open(image_path('sample.png'))
|
167
|
+
background = FreeImage::Bitmap.open(image_path('gradient.png'))
|
168
|
+
# Need to make sure the background image is the same size
|
169
|
+
background = background.rescale(image.width, image.height, :box)
|
170
|
+
composite = image.composite(background)
|
171
|
+
|
172
|
+
Sample[link:cookbook/sample.png]
|
173
|
+
SampleCompositeColor[link:cookbook/sample_composite.png]
|
174
|
+
|
175
|
+
== Manipulating An Image
|
176
|
+
\FreeImage also allows you to directly access each pixel in an image.
|
177
|
+
As an example, let's create an image that has a gradient from
|
178
|
+
blue in the top left corner to green in the bottom right
|
179
|
+
|
180
|
+
image = FreeImage::Bitmap.create(300, 300, 24)
|
181
|
+
color = FreeImage::RGBQuad.new
|
182
|
+
|
183
|
+
image.width.times do |x|
|
184
|
+
image.height.times do |y|
|
185
|
+
color[:green] = (x.to_f/image.width) * 255
|
186
|
+
color[:blue] = (y.to_f/image.height) * 255
|
187
|
+
image.set_pixel_color(x, y, color)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
image.save('images/gradient.png', :png)
|
192
|
+
|
193
|
+
Gradient[link:cookbook/gradient.png]
|
194
|
+
|
195
|
+
You can use a similar technique as another solution to drawing a border around a
|
196
|
+
thumbnail as discussed above.
|
197
|
+
|
198
|
+
== Using Scanlines
|
199
|
+
Scanlines[rdoc-ref:FreeImage::Scanline] provide low level access to image data.
|
200
|
+
The only lower-level access is working with the actual raw bytes, which you can do
|
201
|
+
via the FreeeImage::Bitmap#bytes method, but its not recommended.
|
202
|
+
|
203
|
+
A scanline represents one row of image data, starting from the bottom. Let's go back
|
204
|
+
to our example above of drawing a red border around a thumbnail.
|
205
|
+
|
206
|
+
# Helper method
|
207
|
+
def set_to_red(color)
|
208
|
+
color[:red] = 255
|
209
|
+
color[:green] = 0
|
210
|
+
color[:blue] = 0
|
211
|
+
end
|
212
|
+
|
213
|
+
# Create a thumbnail
|
214
|
+
image = FreeImage::Bitmap.open('images/lena.png')
|
215
|
+
thumbnail = image.make_thumbnail(100)
|
216
|
+
|
217
|
+
# Draw bottom border 4 pixels tall
|
218
|
+
(0..3).each do |index|
|
219
|
+
scanline = thumbnail.scanline(index)
|
220
|
+
scanline.each do |color|
|
221
|
+
set_to_red(color)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Draw top border 4 pixels tall
|
226
|
+
((thumbnail.height - 5)..(thumbnail.height - 1)).each do |index|
|
227
|
+
scanline = thumbnail.scanline(index)
|
228
|
+
scanline.each do |color|
|
229
|
+
set_to_red(color)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# We could skip top and bottom 4 scanlines since
|
234
|
+
# already drew them.
|
235
|
+
thumbnail.height.each do |index|
|
236
|
+
scanline = thumbnail.scanline(index)
|
237
|
+
# Draw left and right borders 4 pixels wide
|
238
|
+
(0..4).each do |index|
|
239
|
+
set_to_red(scanline[index])
|
240
|
+
end
|
241
|
+
|
242
|
+
((thumbnail.width - 5)..(thumbnail.width - 1)).each do |index|
|
243
|
+
set_to_red(scanline[index])
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
thumbnail.save("images/lena_thumbnail_border_scanline.png", :png)
|
248
|
+
|
238
249
|
ThumbnailBorderScanline[link:cookbook/lena_thumbnail_border_scanline.png]
|