update to use minimagick instead, and modernize the gem a bit. didn't touch the rails parts, just the zoomifier code
This commit is contained in:
parent
0b40e0019d
commit
66f550139b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
*.swp
|
*.swp
|
||||||
|
Gemfile.lock
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'open-uri'
|
require 'open-uri'
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
require 'rmagick'
|
require 'mini_magick'
|
||||||
|
|
||||||
# Breaks up images into tiles suitable for viewing with Zoomify.
|
# Breaks up images into tiles suitable for viewing with Zoomify.
|
||||||
# See http://zoomify.com/ for more details.
|
# See http://zoomify.com/ for more details.
|
||||||
@ -42,17 +42,23 @@ module Zoomifier
|
|||||||
tmpdir = "#{outputdir}/tmp"
|
tmpdir = "#{outputdir}/tmp"
|
||||||
Dir.mkdir(tmpdir)
|
Dir.mkdir(tmpdir)
|
||||||
tilesdir = nil
|
tilesdir = nil
|
||||||
image = Magick::Image.read(filename).first.strip!
|
original_image = MiniMagick::Image.open(filename)
|
||||||
# Each level of zoom is a factor of 2. Here we obtain the number of zooms
|
# Each level of zoom is a factor of 2. Here we obtain the number of zooms
|
||||||
# allowed by the original file dimensions and the constant tile size.
|
# allowed by the original file dimensions and the constant tile size.
|
||||||
levels = (Math.log([image.rows, image.columns].max.to_f / TILESIZE) / Math.log(2)).ceil
|
levels = (Math.log([original_image['height'], original_image['width']].max.to_f / TILESIZE) / Math.log(2)).ceil
|
||||||
tiles = 0
|
tiles = 0
|
||||||
(0..levels).each do |level|
|
(0..levels).each do |level|
|
||||||
n = levels - level
|
n = levels - level
|
||||||
# Obtain the image to tile for this level. The 0th level should consist
|
# Obtain the image to tile for this level. The 0th level should consist
|
||||||
# of one tile, while the highest level should be the original image.
|
# of one tile, while the highest level should be the original image.
|
||||||
level_image = image.resize(image.columns >> n, image.rows >> n)
|
|
||||||
tiles(tmpdir, level, level_image) do |filename|
|
create_image = proc {
|
||||||
|
image = MiniMagick::Image.open(filename)
|
||||||
|
image.resize("#{image['width'] >> n}x#{image['height'] >> n}")
|
||||||
|
image
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles(tmpdir, level, create_image) do |filename|
|
||||||
# The tile images are chunked into directories named TileGroupN, N
|
# The tile images are chunked into directories named TileGroupN, N
|
||||||
# starting at 0 and increasing monotonically. Each directory contains
|
# starting at 0 and increasing monotonically. Each directory contains
|
||||||
# at most 256 images. The images are sorted by level, tile row, and
|
# at most 256 images. The images are sorted by level, tile row, and
|
||||||
@ -66,34 +72,36 @@ module Zoomifier
|
|||||||
tiles += 1
|
tiles += 1
|
||||||
end
|
end
|
||||||
# Rmagick needs a bit of help freeing image memory.
|
# Rmagick needs a bit of help freeing image memory.
|
||||||
level_image = nil
|
|
||||||
GC.start
|
GC.start
|
||||||
end
|
end
|
||||||
File.open("#{outputdir}/ImageProperties.xml", 'w') do |f|
|
File.open("#{outputdir}/ImageProperties.xml", 'w') do |f|
|
||||||
f.write("<IMAGE_PROPERTIES WIDTH=\"#{image.columns}\" HEIGHT=\"#{image.rows}\" NUMTILES=\"#{tiles}\" NUMIMAGES=\"1\" VERSION=\"1.8\" TILESIZE=\"#{TILESIZE}\" />")
|
f.write("<IMAGE_PROPERTIES WIDTH=\"#{original_image['width']}\" HEIGHT=\"#{original_image['height']}\" NUMTILES=\"#{tiles}\" NUMIMAGES=\"1\" VERSION=\"1.8\" TILESIZE=\"#{TILESIZE}\" />")
|
||||||
end
|
end
|
||||||
Dir.rmdir(tmpdir)
|
FileUtils.rm_rf(tmpdir)
|
||||||
outputdir
|
outputdir
|
||||||
end
|
end
|
||||||
|
|
||||||
# Splits the given image up into images of TILESIZE, writes them to the
|
# Splits the given image up into images of TILESIZE, writes them to the
|
||||||
# given directory, and yields their names
|
# given directory, and yields their names
|
||||||
def self.tiles(dir, level, image)
|
def self.tiles(dir, level, image)
|
||||||
slice(image.rows).each_with_index do |y_slice, j|
|
my_image = image.()
|
||||||
slice(image.columns).each_with_index do |x_slice, i|
|
|
||||||
|
original_width = my_image['width']
|
||||||
|
original_height = my_image['height']
|
||||||
|
|
||||||
|
my_image.write "#{dir}/_tmp.jpg"
|
||||||
|
|
||||||
|
slice(original_height).each_with_index do |y_slice, j|
|
||||||
|
slice(original_width).each_with_index do |x_slice, i|
|
||||||
# The images are named "level-column-row.jpg"
|
# The images are named "level-column-row.jpg"
|
||||||
filename = "#{level}-#{i}-#{j}.jpg"
|
filename = "#{level}-#{i}-#{j}.jpg"
|
||||||
tile_image = image.crop(x_slice[0], y_slice[0], x_slice[1], y_slice[1])
|
|
||||||
tile_image.write("#{dir}/#{filename}") do
|
new_image = MiniMagick::Image.open("#{dir}/_tmp.jpg")
|
||||||
# FIXME - the images end up being 4-5x larger than those produced
|
|
||||||
# by Zoomifier EZ and friends... no idea why just yet, except to note
|
new_image.crop("#{x_slice[1]}x#{y_slice[1]}+#{x_slice[0]}+#{y_slice[0]}")
|
||||||
# that the density of these tiles ends up being 400x400, while
|
new_image.strip
|
||||||
# everybody else produces tiles at 72x72. Can't see why that would
|
new_image.write("#{dir}/#{filename}")
|
||||||
# matter though...
|
|
||||||
self.quality = 80
|
|
||||||
end
|
|
||||||
# Rmagick needs a bit of help freeing image memory.
|
# Rmagick needs a bit of help freeing image memory.
|
||||||
tile_image = nil
|
|
||||||
GC.start
|
GC.start
|
||||||
yield filename
|
yield filename
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@ describe Zoomifier do
|
|||||||
Zoomifier.should respond_to(:zoomify)
|
Zoomifier.should respond_to(:zoomify)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "all images", :shared => true do
|
shared_examples "all images" do
|
||||||
before(:all) do
|
before(:all) do
|
||||||
FileUtils.rm_rf(@output)
|
FileUtils.rm_rf(@output)
|
||||||
Zoomifier::zoomify(@input)
|
Zoomifier::zoomify(@input)
|
||||||
@ -31,9 +31,9 @@ describe Zoomifier do
|
|||||||
|
|
||||||
it "should create tiles of 256x256 or less" do
|
it "should create tiles of 256x256 or less" do
|
||||||
@tiles.each do |file|
|
@tiles.each do |file|
|
||||||
image = Magick::Image.read(@output + file).first
|
image = MiniMagick::Image.open(@output + file)
|
||||||
image.rows.should <= 256
|
image['width'].should <= 256
|
||||||
image.columns.should <= 256
|
image['height'].should <= 256
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -13,5 +13,7 @@ Gem::Specification.new do |s|
|
|||||||
s.default_executable = 'zoomify'
|
s.default_executable = 'zoomify'
|
||||||
s.has_rdoc = true
|
s.has_rdoc = true
|
||||||
s.extra_rdoc_files = ['README.markdown']
|
s.extra_rdoc_files = ['README.markdown']
|
||||||
s.add_dependency('rmagick')
|
|
||||||
|
s.add_dependency('mini_magick')
|
||||||
|
s.add_development_dependency 'rspec'
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user