Skip to content

Commit

Permalink
Zoomify image's initial size correction
Browse files Browse the repository at this point in the history
  • Loading branch information
Fiser33 committed Dec 11, 2016
1 parent e594280 commit 30fb716
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 33 deletions.
2 changes: 2 additions & 0 deletions Example/iOSTiledViewer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@
PROVISIONING_PROFILE = "7a270d4e-8a9e-44bc-bfa6-b5b4235feffc";
PROVISIONING_PROFILE_SPECIFIER = "IIIF Development";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
Expand Down Expand Up @@ -495,6 +496,7 @@
PROVISIONING_PROFILE = "e97c827d-2581-4145-ae4f-2fcd5ed68ce0";
PROVISIONING_PROFILE_SPECIFIER = "IIIF Distribution";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
Expand Down
2 changes: 1 addition & 1 deletion iOSTiledViewer.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = 'iOSTiledViewer'
s.version = '0.1.4'
s.version = '0.1.5'
s.summary = 'High-resolution images Viewer.'

# This description is used to generate tags and improve search results.
Expand Down
2 changes: 1 addition & 1 deletion iOSTiledViewer/Classes/IIIF/IIIFImageDescriptorV1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ extension IIIFImageDescriptorV1: ITVImageDescriptor {
}

// Methods
mutating func sizeToFit(size: CGSize, zoomScale: CGFloat) -> CGSize {
mutating func sizeToFit(size: CGSize) -> CGSize {
let imageSize = CGSize(width: width, height: height)
var aspectFitSize = size
let mW = aspectFitSize.width / imageSize.width
Expand Down
2 changes: 1 addition & 1 deletion iOSTiledViewer/Classes/IIIF/IIIFImageDescriptorV2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ extension IIIFImageDescriptorV2: ITVImageDescriptor {
}


mutating func sizeToFit(size: CGSize, zoomScale: CGFloat) -> CGSize {
mutating func sizeToFit(size: CGSize) -> CGSize {
let imageSize = CGSize(width: width, height: height)
var aspectFitSize = size
let mW = aspectFitSize.width / imageSize.width
Expand Down
2 changes: 1 addition & 1 deletion iOSTiledViewer/Classes/ITVImageDescriptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ protocol ITVImageDescriptor {
func getBackgroundUrl() -> URL?

/// Note - Protocol may be implemented by struct, that would need to store size and scale values for further computations. To allow that, function has to be marked as mutating.
mutating func sizeToFit(size: CGSize, zoomScale: CGFloat) -> CGSize
mutating func sizeToFit(size: CGSize) -> CGSize
}
21 changes: 13 additions & 8 deletions iOSTiledViewer/Classes/ITVScrollView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ open class ITVScrollView: UIScrollView {

fileprivate extension ITVScrollView {

// Resizin tiled view to fit in scroll view
// Resizing tiled view to fit in scroll view
fileprivate func resizeTiledView(image: ITVImageDescriptor) -> ITVImageDescriptor {
var mutableImage = image
let newSize = mutableImage.sizeToFit(size: frame.size, zoomScale: tiledView.contentScaleFactor)
let newSize = mutableImage.sizeToFit(size: frame.size)
tiledView.frame = CGRect(origin: CGPoint.zero, size: newSize)
scrollViewDidZoom(self)
return mutableImage
Expand All @@ -250,6 +250,7 @@ fileprivate extension ITVScrollView {
maximumZoomScale = scales.last!
minimumZoomScale = scales.first!
zoomScale = minimumZoomScale
changeLevel(forScale: minimumZoomScale)
tiledView.image = image
licenseView.imageDescriptor = image

Expand All @@ -274,6 +275,15 @@ fileprivate extension ITVScrollView {
semaphore.wait()
return result
}

fileprivate func changeLevel(forScale scale: CGFloat) {
// redraw image by setting contentScaleFactor on tiledView
let level = Int(round(log2(scale)))
if level != lastLevel {
tiledView.contentScaleFactor = pow(2.0, CGFloat(level))
lastLevel = level
}
}
}

/// MARK: UIScrollViewDelegate implementation
Expand All @@ -292,12 +302,7 @@ extension ITVScrollView: UIScrollViewDelegate {
}

public func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
// redraw image by setting contentScaleFactor on tiledView
let level = Int(round(log2(scale)))
if level != lastLevel {
tiledView.contentScaleFactor = pow(2.0, CGFloat(level))
lastLevel = level
}
changeLevel(forScale: scale)
}

public func viewForZooming(in scrollView: UIScrollView) -> UIView? {
Expand Down
24 changes: 13 additions & 11 deletions iOSTiledViewer/Classes/ITVTiledView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ class ITVTiledView: UIView {

override func draw(_ rect: CGRect) {

guard image != nil, let context = UIGraphicsGetCurrentContext() else {
guard image != nil, let context = UIGraphicsGetCurrentContext(), !rect.isInfinite, !rect.isNull else {
return
}

let viewScale = self.contentScaleFactor
let viewSize = bounds.width * contentScaleFactor

let scale = CGFloat(image.width)/viewSize//.width
let scale = CGFloat(image.width)/viewSize

let tiledLayer = self.layer as! CATiledLayer
let tileSize = tiledLayer.tileSize
Expand All @@ -73,16 +73,14 @@ class ITVTiledView: UIView {
let row = Int(rect.midY * viewScale / tileSize.height)
let level = self.level

var requestURL: URL!
/// TODO: make borders setting modifiable to user as well
let displayTileBorders = false

let cacheKey = "\(level)/\(column)_\(row)"
let cacheKey = "\(level)-\(column)-\(row)"
if let image = imageCache[cacheKey] {
image.draw(in: rect)
}
else {
requestURL = image.getUrl(x: column, y: row, level: level, scale: scale)
else if let requestURL = image.getUrl(x: column, y: row, level: level, scale: scale) {
URLSession.shared.dataTask(with: requestURL, completionHandler: { (data, response, error) in
if data != nil , let image = UIImage(data: data!) {
self.imageCache[cacheKey] = image
Expand All @@ -98,7 +96,7 @@ class ITVTiledView: UIView {

if displayTileBorders {
UIColor.green.set()
context.setLineWidth(2)
context.setLineWidth(1)
context.stroke(rect)
}
}
Expand All @@ -107,9 +105,13 @@ class ITVTiledView: UIView {
fileprivate func initBackground() {
if let imageUrl = image.getBackgroundUrl() {
URLSession.shared.dataTask(with: imageUrl, completionHandler: { (data, response, error) in
if data != nil, let image = UIImage(data: data!) {
if data != nil,
let image = UIImage(data: data!),
let scaledImage = self.scaledImage(image: image, newSize: self.bounds.size) {
DispatchQueue.main.sync {
self.backgroundColor = UIColor(patternImage: self.scaledImage(image: image, newSize: self.bounds.size))
let originalScaleFactor = self.contentScaleFactor
self.backgroundColor = UIColor(patternImage: scaledImage)
self.contentScaleFactor = originalScaleFactor
self.setNeedsLayout()
}
}
Expand All @@ -118,11 +120,11 @@ class ITVTiledView: UIView {
}

// Resize UIImage to fit given size.
fileprivate func scaledImage(image: UIImage, newSize: CGSize) -> UIImage {
fileprivate func scaledImage(image: UIImage, newSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image.draw(in: CGRect(origin: CGPoint.zero, size: newSize))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
return newImage
}
}
33 changes: 23 additions & 10 deletions iOSTiledViewer/Classes/Zoomify/ZoomifyImageDescriptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,20 @@ struct ZoomifyImageDescriptor {
return tilesForLevel[level]
}

fileprivate mutating func saveZoomScales(_ originalSize: CGSize, _ aspectFitSize: CGSize, _ viewScale: CGFloat) {
fileprivate func numberOfTiles(_ level: CGFloat) -> Int {
return numberOfTiles(Int(level))
}

fileprivate mutating func saveZoomScales(_ originalSize: CGSize, _ aspectFitSize: CGSize) {
let ratioW = originalSize.width / aspectFitSize.width
let ratioH = originalSize.height / aspectFitSize.height
_zoomScales = [min(ratioW, ratioH)]
let minimumScale = min(ratioW, ratioH)
_zoomScales = [minimumScale]
for i in 1...depth {
_zoomScales.append(CGFloat(powf(2, Float(i))))
let scale = CGFloat(powf(2, Float(i)))
if scale > minimumScale {
_zoomScales.append(scale)
}
}
}
}
Expand Down Expand Up @@ -134,12 +142,14 @@ extension ZoomifyImageDescriptor: ITVImageDescriptor {
return URL(string: "\(baseUrl)/\(group)/\(file).\(format)")
}

mutating func sizeToFit(size: CGSize, zoomScale: CGFloat) -> CGSize {
let sum = Float(width + height)
let totalTiles = Float(numberOfTiles(2) - numberOfTiles(1))
let numTilesX = CGFloat(round(totalTiles / (sum / Float(width))))
let numTilesY = CGFloat(round(totalTiles / (sum / Float(height))))
let tile = _tileSize.width / zoomScale
mutating func sizeToFit(size: CGSize) -> CGSize {
// We have to
let area = Float(width * height)
let totalTiles = Float(tilesForLevel.last! - tilesForLevel[tilesForLevel.count-2])
let coeficient = sqrt(area / totalTiles)
let numTilesX = CGFloat( Float(width)/coeficient )
let numTilesY = CGFloat( Float(height)/coeficient )
let tile = _tileSize.width / Constants.SCREEN_SCALE

let imageSize = CGSize(width: width, height: height)
var aspectFitSize = CGSize(width: numTilesX*tile, height: numTilesY*tile)
Expand All @@ -152,7 +162,10 @@ extension ZoomifyImageDescriptor: ITVImageDescriptor {
aspectFitSize.height = mW * imageSize.height
}

saveZoomScales(size, aspectFitSize, zoomScale)
let trasnformation = Constants.SCREEN_SCALE/CGFloat(powf(2.0, Float(depth)))
aspectFitSize = aspectFitSize.applying(CGAffineTransform(scaleX: trasnformation, y: trasnformation))

saveZoomScales(size, aspectFitSize)
return aspectFitSize
}
}

0 comments on commit 30fb716

Please sign in to comment.