Skip to content

Commit

Permalink
Allow a Fog::Storage uploader to be passed in for uploading of genera…
Browse files Browse the repository at this point in the history
…ted tiles
  • Loading branch information
mzikherman committed Oct 16, 2014
1 parent d027a89 commit 499f45e
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 25 deletions.
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ gemspec

gem "rspec"
gem "rake"
group :test do
gem "fog"
gem "pry"
end
30 changes: 24 additions & 6 deletions lib/dzt/tiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,38 @@ class Tiler
# @param overlap Size, in pixels, of the overlap between tiles (default: 2)
# @param overwrite If true, overwrites existing tiles (default: false)
# @param destination: Full directory in which to output tiles.
# @param uploader: Fog::Storage object
# @param s3_key: S3 key to store resultant files.
# @param s3_bucket: S3 bucket to store resultant files.
#
def initialize(options)
@tile_source = options[:source]
raise "Missing options[:source]." unless @tile_source

@tile_source = Magick::Image.read(@tile_source)[0] if @tile_source.is_a?(String)
@tile_size = options[:size] || DEFAULT_TILE_SIZE
@tile_overlap = options[:overlap] || DEFAULT_TILE_OVERLAP
@tile_format = options[:format] || DEFAULT_TILE_FORMAT

@max_tiled_height = @tile_source.rows
@max_tiled_width = @tile_source.columns

@tile_quality = options[:quality] || DEFAULT_QUALITY
@overwrite = options[:overwrite] || false
@destination = options[:destination] || File.join(Dir.pwd, "tiles")
@uploader = options[:uploader]

@store_path = @uploader ? options[:s3_key] : options[:destination] || File.join(Dir.pwd, "tiles")
@s3_bucket = options[:s3_bucket]
@s3_acl = options[:s3_acl]
end

##
# Generates the DZI-formatted tiles and sets necessary metadata on this object.
# Uses a default tile size of 512 pixels, with a default overlap of 2 pixel.
##
def slice!(&block)
if ! @overwrite && File.directory?(@destination) && ! Dir["@{@destination}/*"].empty?
raise "Output directory #{@destination} already exists!"
if !! @uploader && ! @overwrite && File.directory?(@store_path) && ! Dir["@{@store_path}/*"].empty?
raise "Output directory #{@store_path} already exists!"
@overwrite ? Rails.logger.warn(msg) : raise(msg)
end

Expand All @@ -48,8 +58,8 @@ def slice!(&block)
max_level(orig_width, orig_height).downto(0) do |level|
width, height = image.columns, image.rows

current_level_dir = File.join(@destination, level.to_s)
FileUtils.mkdir_p(current_level_dir)
current_level_dir = File.join(@store_path, level.to_s)
FileUtils.mkdir_p(current_level_dir) unless @uploader

if block_given?
yield current_level_dir
Expand Down Expand Up @@ -120,7 +130,15 @@ def save_cropped_image(src, dest, x, y, width, height, quality = 75)
# The crop method retains the offset information in the cropped image.
# To reset the offset data, adding true as the last argument to crop.
cropped = img.crop(x, y, width, height, true)
cropped.write(dest) { @quality = quality }
if @uploader
full_path = "#{@s3_key}/#{dest}"
@uploader.put_object(@s3_bucket, full_path, cropped.to_blob { @quality = quality },
'Content-Type' => cropped.mime_type,
'x-amz-acl' => @s3_acl
)
else
cropped.write(dest) { @quality = quality }
end
end
end
end
8 changes: 4 additions & 4 deletions spec/dzt/dzt_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
describe "#help" do
it "displays help" do
help = `"#{@binary}" help`
help.should include "dzt - Tile images into deep-zoom tiles"
expect(help).to include "dzt - Tile images into deep-zoom tiles"
end
end
describe "#slice" do
it "slices an image" do
goya = File.join(@fixtures_dir, "francisco-jose-de-goya-y-lucientes-senora-sabasa-garcia.jpg")
Dir.mktmpdir do |tmpdir|
`"#{@binary}" slice "#{goya}" --output #{tmpdir}`
Dir["#{tmpdir}/*"].map { |dir| dir.split("/").last.to_i }.sort.should == (0..12).to_a
expect(Dir["#{tmpdir}/*"].map { |dir| dir.split("/").last.to_i }.sort).to eq((0..12).to_a)
# center
image = Magick::Image::read("#{tmpdir}/11/1_1.jpg").first
image.columns.should == 512
image.rows.should == 512
expect(image.columns).to eq(512)
expect(image.rows).to eq(512)
end
end
end
Expand Down
69 changes: 55 additions & 14 deletions spec/dzt/tiler_spec.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,66 @@
require 'spec_helper'
require 'pry'
require 'RMagick'
include Magick

describe DZT::Tiler do
before :each do
@fixtures_dir = File.expand_path(File.join(__FILE__, '../../fixtures'))
end
it "slices an image" do
Dir.mktmpdir do |tmpdir|
tiler = DZT::Tiler.new(
context 'storing files locally' do
it "slices an image and stores files" do
Dir.mktmpdir do |tmpdir|
tiler = DZT::Tiler.new(
source: File.join(@fixtures_dir, "francisco-jose-de-goya-y-lucientes-senora-sabasa-garcia.jpg"),
destination: tmpdir
)
tiler.slice!
expect(Dir["#{tmpdir}/*"].map { |dir| dir.split("/").last.to_i }.sort).to eq((0..12).to_a)
# center
image = Magick::Image::read("#{tmpdir}/11/1_1.jpg").first
expect(image.columns).to eq(512)
expect(image.rows).to eq(512)
# edge
image = Magick::Image::read("#{tmpdir}/11/2_2.jpg").first
expect(image.columns).to eq(168)
expect(image.rows).to eq(443)
end
end
end
context 'uploading resultant files to S3' do
before :each do
Fog.mock!
Fog::Mock.reset
@s3_uploader = Fog::Storage.new(
provider: 'AWS',
aws_access_key_id: 'id',
aws_secret_access_key: 'secret'
)
@bucket = @s3_uploader.directories.create(key: 'tiled-images')
@tiler = DZT::Tiler.new(
source: File.join(@fixtures_dir, "francisco-jose-de-goya-y-lucientes-senora-sabasa-garcia.jpg"),
destination: tmpdir
s3_key: 'dztiles',
s3_bucket: 'tiled-images',
uploader: @s3_uploader,
s3_acl: 'public-read'
)
tiler.slice!
Dir["#{tmpdir}/*"].map { |dir| dir.split("/").last.to_i }.sort.should == (0..12).to_a
# center
image = Magick::Image::read("#{tmpdir}/11/1_1.jpg").first
image.columns.should == 512
image.rows.should == 512
# edge
image = Magick::Image::read("#{tmpdir}/11/2_2.jpg").first
image.columns.should == 168
image.rows.should == 443
end
it 'slices the images' do
@tiler.slice!
file = @bucket.files.select { |f| f.key == '/dztiles/11/1_1.jpg' }.first
image = Image.from_blob(file.body).first
expect(image.columns).to eq(512)
expect(image.rows).to eq(512)
file = @bucket.files.select { |f| f.key == '/dztiles/11/2_2.jpg' }.first
image = Image.from_blob(file.body).first
expect(image.columns).to eq(168)
expect(image.rows).to eq(443)
end
it 'stores the files properly' do
expect_any_instance_of(Fog::Storage::AWS::Mock).to receive(:put_object).at_least(53).times do |*args|
expect(args.last).to eq("Content-Type" => "image/jpeg", "x-amz-acl" => "public-read")
end
@tiler.slice!
end
end
end
2 changes: 1 addition & 1 deletion spec/dzt/version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

describe DZT do
it "has a version" do
DZT::VERSION.should_not be_nil
expect(DZT::VERSION).to_not be_nil
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
require 'rspec'
require 'tmpdir'
require 'dzt'
require 'fog'

0 comments on commit 499f45e

Please sign in to comment.