Merge branch 'charlesmchen/imageEditorFlip'

This commit is contained in:
Matthew Chen 2019-02-26 17:43:26 -05:00
commit 05cc3c00f2
3 changed files with 51 additions and 15 deletions

View file

@ -265,6 +265,15 @@ public class ImageEditorCanvasView: UIView {
public class func updateImageLayer(imageLayer: CALayer, viewSize: CGSize, imageSize: CGSize, transform: ImageEditorTransform) {
imageLayer.frame = imageFrame(forViewSize: viewSize, imageSize: imageSize, transform: transform)
// This is the only place the isFlipped flag is consulted.
// We deliberately do _not_ use it in the affine transforms, etc.
// so that:
//
// * It doesn't affect text content & brush strokes.
// * To not complicate the other "coordinate system math".
let transform = CGAffineTransform.identity.scaledBy(x: transform.isFlipped ? -1 : +1, y: 1)
imageLayer.setAffineTransform(transform)
}
public class func imageFrame(forViewSize viewSize: CGSize, imageSize: CGSize, transform: ImageEditorTransform) -> CGRect {

View file

@ -101,6 +101,9 @@ class ImageEditorCropViewController: OWSViewController {
let zoom2xButton = OWSButton(title: "Zoom 2x") { [weak self] in
self?.zoom2xButtonPressed()
}
let flipButton = OWSButton(title: "Flip") { [weak self] in
self?.flipButtonPressed()
}
// MARK: - Header
@ -149,6 +152,7 @@ class ImageEditorCropViewController: OWSViewController {
// MARK: - Footer
let footer = UIStackView(arrangedSubviews: [
flipButton,
rotate90Button,
rotate45Button,
UIView.hStretchingSpacer(),
@ -418,7 +422,8 @@ class ImageEditorCropViewController: OWSViewController {
updateTransform(ImageEditorTransform(outputSizePixels: gestureStartTransform.outputSizePixels,
unitTranslation: newUnitTranslation,
rotationRadians: newRotationRadians,
scaling: newScaling).normalize(srcImageSizePixels: model.srcImageSizePixels))
scaling: newScaling,
isFlipped: gestureStartTransform.isFlipped).normalize(srcImageSizePixels: model.srcImageSizePixels))
default:
break
}
@ -552,7 +557,8 @@ class ImageEditorCropViewController: OWSViewController {
let naiveTransform = ImageEditorTransform(outputSizePixels: croppedOutputSizePixels,
unitTranslation: transform.unitTranslation,
rotationRadians: transform.rotationRadians,
scaling: transform.scaling)
scaling: transform.scaling,
isFlipped: transform.isFlipped)
let naiveImageFrameOld = ImageEditorCanvasView.imageFrame(forViewSize: transform.outputSizePixels, imageSize: model.srcImageSizePixels, transform: naiveTransform)
let naiveImageFrameNew = ImageEditorCanvasView.imageFrame(forViewSize: croppedOutputSizePixels, imageSize: model.srcImageSizePixels, transform: naiveTransform)
let scalingDeltaX = naiveImageFrameNew.width / naiveImageFrameOld.width
@ -590,7 +596,8 @@ class ImageEditorCropViewController: OWSViewController {
updateTransform(ImageEditorTransform(outputSizePixels: croppedOutputSizePixels,
unitTranslation: unitTranslation,
rotationRadians: transform.rotationRadians,
scaling: scaling).normalize(srcImageSizePixels: model.srcImageSizePixels))
scaling: scaling,
isFlipped: transform.isFlipped).normalize(srcImageSizePixels: model.srcImageSizePixels))
}
private func handleNormalPanGesture(_ gestureRecognizer: ImageEditorPanGestureRecognizer) {
@ -614,7 +621,8 @@ class ImageEditorCropViewController: OWSViewController {
updateTransform(ImageEditorTransform(outputSizePixels: gestureStartTransform.outputSizePixels,
unitTranslation: newUnitTranslation,
rotationRadians: gestureStartTransform.rotationRadians,
scaling: gestureStartTransform.scaling).normalize(srcImageSizePixels: model.srcImageSizePixels))
scaling: gestureStartTransform.scaling,
isFlipped: gestureStartTransform.isFlipped).normalize(srcImageSizePixels: model.srcImageSizePixels))
}
private func cropRegion(forGestureRecognizer gestureRecognizer: ImageEditorPanGestureRecognizer) -> CropRegion? {
@ -691,7 +699,8 @@ class ImageEditorCropViewController: OWSViewController {
updateTransform(ImageEditorTransform(outputSizePixels: outputSizePixels,
unitTranslation: unitTranslation,
rotationRadians: rotationRadians,
scaling: scaling).normalize(srcImageSizePixels: model.srcImageSizePixels))
scaling: scaling,
isFlipped: transform.isFlipped).normalize(srcImageSizePixels: model.srcImageSizePixels))
}
@objc public func zoom2xButtonPressed() {
@ -700,9 +709,18 @@ class ImageEditorCropViewController: OWSViewController {
let rotationRadians = transform.rotationRadians
let scaling = transform.scaling * 2.0
updateTransform(ImageEditorTransform(outputSizePixels: outputSizePixels,
unitTranslation: unitTranslation,
rotationRadians: rotationRadians,
scaling: scaling).normalize(srcImageSizePixels: model.srcImageSizePixels))
unitTranslation: unitTranslation,
rotationRadians: rotationRadians,
scaling: scaling,
isFlipped: transform.isFlipped).normalize(srcImageSizePixels: model.srcImageSizePixels))
}
@objc public func flipButtonPressed() {
updateTransform(ImageEditorTransform(outputSizePixels: transform.outputSizePixels,
unitTranslation: transform.unitTranslation,
rotationRadians: transform.rotationRadians,
scaling: transform.scaling,
isFlipped: !transform.isFlipped).normalize(srcImageSizePixels: model.srcImageSizePixels))
}
@objc public func resetButtonPressed() {

View file

@ -62,15 +62,19 @@ public class ImageEditorTransform: NSObject {
public let rotationRadians: CGFloat
// x >= 1.0.
public let scaling: CGFloat
// Flipping is horizontal.
public let isFlipped: Bool
public init(outputSizePixels: CGSize,
unitTranslation: CGPoint,
rotationRadians: CGFloat,
scaling: CGFloat) {
scaling: CGFloat,
isFlipped: Bool) {
self.outputSizePixels = outputSizePixels
self.unitTranslation = unitTranslation
self.rotationRadians = rotationRadians
self.scaling = scaling
self.isFlipped = isFlipped
}
public class func defaultTransform(srcImageSizePixels: CGSize) -> ImageEditorTransform {
@ -78,7 +82,8 @@ public class ImageEditorTransform: NSObject {
return ImageEditorTransform(outputSizePixels: srcImageSizePixels,
unitTranslation: .zero,
rotationRadians: 0.0,
scaling: 1.0).normalize(srcImageSizePixels: srcImageSizePixels)
scaling: 1.0,
isFlipped: false).normalize(srcImageSizePixels: srcImageSizePixels)
}
public func affineTransform(viewSize: CGSize) -> CGAffineTransform {
@ -133,7 +138,8 @@ public class ImageEditorTransform: NSObject {
let naiveTransform = ImageEditorTransform(outputSizePixels: outputSizePixels,
unitTranslation: .zero,
rotationRadians: rotationRadians,
scaling: scaling)
scaling: scaling,
isFlipped: self.isFlipped)
let naiveAffineTransform = naiveTransform.affineTransform(viewSize: viewBounds.size)
var naiveViewportMinCanvas = CGPoint.zero
var naiveViewportMaxCanvas = CGPoint.zero
@ -192,7 +198,8 @@ public class ImageEditorTransform: NSObject {
return ImageEditorTransform(outputSizePixels: outputSizePixels,
unitTranslation: unitTranslation,
rotationRadians: rotationRadians,
scaling: scaling)
scaling: scaling,
isFlipped: self.isFlipped)
}
public override func isEqual(_ object: Any?) -> Bool {
@ -202,7 +209,8 @@ public class ImageEditorTransform: NSObject {
return (outputSizePixels == other.outputSizePixels &&
unitTranslation == other.unitTranslation &&
rotationRadians == other.rotationRadians &&
scaling == other.scaling)
scaling == other.scaling &&
isFlipped == other.isFlipped)
}
public override var hash: Int {
@ -211,11 +219,12 @@ public class ImageEditorTransform: NSObject {
unitTranslation.x.hashValue ^
unitTranslation.y.hashValue ^
rotationRadians.hashValue ^
scaling.hashValue)
scaling.hashValue ^
isFlipped.hashValue)
}
open override var description: String {
return "[outputSizePixels: \(outputSizePixels), unitTranslation: \(unitTranslation), rotationRadians: \(rotationRadians), scaling: \(scaling)]"
return "[outputSizePixels: \(outputSizePixels), unitTranslation: \(unitTranslation), rotationRadians: \(rotationRadians), scaling: \(scaling), isFlipped: \(isFlipped)]"
}
}