Skip to content

Commit

Permalink
Merge pull request #7 from guhungry/Feature/add-rotate-image
Browse files Browse the repository at this point in the history
Feature : Rotate Image
  • Loading branch information
guhungry authored Jun 4, 2024
2 parents df40ade + 6dfa0c3 commit a82f95e
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 5 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,19 @@ Overlay image on top of background image
| position | CGPoint | Yes | Position of overlay image in background image |

### [image flip]
Flip the image horizontally and/or vertically
Flip the image horizontally, vertically or both

| NAME | TYPE | REQUIRED | DESCRIPTION |
|------------|-----------------------|----------|------------------------------------------------------------------------|
| mode | FlipMode | Yes | Flip mode .Vertical or .Horizontal or .Both |

### [image rotate]
Rotate the image 90°, 180° or 270°

| NAME | TYPE | REQUIRED | DESCRIPTION |
|------------|-----------------------|----------|------------------------------------------------------------------------|
| mode | RotationMode | Yes | Rotation mode .R90 (90° Clockwise), .R180 (180° Half Rotation) or .R270 (270° Clockwise, aka 90° Counterclockwise) |


## Usage FileUtils

Expand Down
6 changes: 5 additions & 1 deletion WCPhotoManipulator.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
CA10C5262BB331B7008464A7 /* FlipMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA10C5252BB331B7008464A7 /* FlipMode.swift */; };
CA11C0FB2C0C1E9B005542AA /* RotationMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA11C0FA2C0C1E9B005542AA /* RotationMode.swift */; };
CC92AF5124D250160061CC87 /* FoolSonarcloud.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92AF5024D250160061CC87 /* FoolSonarcloud.m */; };
CC92AF6A24D545070061CC87 /* BitmapUtilsSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92AF6924D545070061CC87 /* BitmapUtilsSwiftTests.swift */; };
CC92AF6C24D558500061CC87 /* FileUtilsSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92AF6B24D558500061CC87 /* FileUtilsSwiftTests.swift */; };
Expand Down Expand Up @@ -53,6 +54,7 @@

/* Begin PBXFileReference section */
CA10C5252BB331B7008464A7 /* FlipMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlipMode.swift; sourceTree = "<group>"; };
CA11C0FA2C0C1E9B005542AA /* RotationMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotationMode.swift; sourceTree = "<group>"; };
CC92AF4F24D250160061CC87 /* FoolSonarcloud.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FoolSonarcloud.h; sourceTree = "<group>"; };
CC92AF5024D250160061CC87 /* FoolSonarcloud.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FoolSonarcloud.m; sourceTree = "<group>"; };
CC92AF6924D545070061CC87 /* BitmapUtilsSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitmapUtilsSwiftTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -123,11 +125,12 @@
children = (
CCC2506B24D05C97000BAC48 /* BitmapUtils.swift */,
CCC2505824CFF0C1000BAC48 /* FileUtils.swift */,
CA10C5252BB331B7008464A7 /* FlipMode.swift */,
CC92AF4F24D250160061CC87 /* FoolSonarcloud.h */,
CC92AF5024D250160061CC87 /* FoolSonarcloud.m */,
CCC2503B24CFDE4B000BAC48 /* MimeUtils.swift */,
CCC2506D24D05EE7000BAC48 /* ResizeMode.swift */,
CA10C5252BB331B7008464A7 /* FlipMode.swift */,
CA11C0FA2C0C1E9B005542AA /* RotationMode.swift */,
CCC2506F24D060C9000BAC48 /* UIImage+PhotoManipulator.swift */,
CCC2505124CFE1D2000BAC48 /* WCPhotoManipulator-Bridging-Header.h */,
);
Expand Down Expand Up @@ -269,6 +272,7 @@
files = (
CCC2506C24D05C97000BAC48 /* BitmapUtils.swift in Sources */,
CCC2507024D060C9000BAC48 /* UIImage+PhotoManipulator.swift in Sources */,
CA11C0FB2C0C1E9B005542AA /* RotationMode.swift in Sources */,
CA10C5262BB331B7008464A7 /* FlipMode.swift in Sources */,
CCC2503C24CFDE4B000BAC48 /* MimeUtils.swift in Sources */,
CC92AF5124D250160061CC87 /* FoolSonarcloud.m in Sources */,
Expand Down
18 changes: 18 additions & 0 deletions WCPhotoManipulator/RotationMode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// RotationMode.swift
// WCPhotoManipulator
//
// Created by Woraphot Chokratanasombat on 2/6/2567 BE.
// Copyright © 2567 BE Woraphot Chokratanasombat. All rights reserved.
//

import Foundation
import UIKit

@objc public enum RotationMode: Int {
case None = 0, R90 = 90, R180 = 180, R270 = 270

func transform() -> CGAffineTransform {
return CGAffineTransformMakeRotation(-CGFloat(self.rawValue) * CGFloat.pi / 180.0)
}
}
16 changes: 15 additions & 1 deletion WCPhotoManipulator/UIImage+PhotoManipulator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,22 @@ public extension UIImage {
return UIImage(ciImage: cgimage)
}

// Flip
@objc func rotate(_ rotateMode: RotationMode) -> UIImage {
if (rotateMode == .None) {
return self
}

let cgimage = ciImage().transformed(by: rotateMode.transform())
return UIImage(ciImage: cgimage)
}

// Flip
@objc func ciImage() -> CIImage {
return (ciImage != nil) ? ciImage! : CIImage(cgImage: cgImage!)
if (ciImage != nil) {
return ciImage!
}

return CIImage(cgImage: cgImage!)
}
}
40 changes: 40 additions & 0 deletions WCPhotoManipulatorTests/UIImage+PhotoManipulatorObjCTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,44 @@ - (void)testFlip_WhenHasBoth_ShouldReturnCorrectly {
XCTAssertEqual(image4.size.width, 800);
XCTAssertEqual(image4.size.height, 530);
}

- (void)testRotate_WhenR90_ShouldReturnCorrectly {
image = [UIImage imageNamedTest:@"background.jpg"];
XCTAssertNotNil(image);

image = [image rotate:RotationModeR90];
XCTAssertNotNil(image);
XCTAssertEqual(image.size.width, 530);
XCTAssertEqual(image.size.height, 800);
}

- (void)testRotate_WhenR180_ShouldReturnCorrectly {
image = [UIImage imageNamedTest:@"background.jpg"];
XCTAssertNotNil(image);

image = [image rotate:RotationModeR180];
XCTAssertNotNil(image);
XCTAssertEqual(image.size.width, 800);
XCTAssertEqual(image.size.height, 530);
}

- (void)testRotate_WhenR270_ShouldReturnCorrectly {
image = [UIImage imageNamedTest:@"background.jpg"];
XCTAssertNotNil(image);

image = [image rotate:RotationModeR270];
XCTAssertNotNil(image);
XCTAssertEqual(image.size.width, 530);
XCTAssertEqual(image.size.height, 800);
}

- (void)testRotate_WhenNone_ShouldReturnCorrectly {
image = [UIImage imageNamedTest:@"background.jpg"];
XCTAssertNotNil(image);

image = [image rotate:RotationModeNone];
XCTAssertNotNil(image);
XCTAssertEqual(image.size.width, 800);
XCTAssertEqual(image.size.height, 530);
}
@end
44 changes: 42 additions & 2 deletions WCPhotoManipulatorTests/UIImage+PhotoManipulatorSwiftTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ class UIImage_PhotoManipulatorSwiftTests: XCTestCase {
XCTAssertEqual(image.size, CGSize(width: 332, height: 70))
XCTAssertEqual(actualColor, expectedColor)
}


// Draw Text
func testDrawText_WhenUseFontAndNoScale_ShouldReturnCorrectly() throws {
image = UIImage.init(namedTest: "background.jpg")
XCTAssertNotNil(image)
Expand Down Expand Up @@ -111,6 +112,7 @@ class UIImage_PhotoManipulatorSwiftTests: XCTestCase {
XCTAssertEqual(image.size, CGSize(width: 800, height: 530))
}

// Overlay Image
func testOverlayImage_WhenNoScale_ShouldReturnCorrectly() throws {
image = UIImage.init(namedTest: "background.jpg")
overlay = UIImage.init(namedTest: "overlay.png")
Expand All @@ -130,7 +132,8 @@ class UIImage_PhotoManipulatorSwiftTests: XCTestCase {
XCTAssertNotNil(image)
XCTAssertEqual(image.size, CGSize(width: 800, height: 530))
}


// Flip
func testFlip_WhenHasHorizontal_ShouldReturnCorrectly() throws {
image = UIImage.init(namedTest: "background.jpg")
XCTAssertNotNil(image)
Expand Down Expand Up @@ -179,4 +182,41 @@ class UIImage_PhotoManipulatorSwiftTests: XCTestCase {
XCTAssertNotNil(image4)
XCTAssertEqual(image4.size, CGSize(width: 800, height: 530))
}

// Rotate
func testRotate_WhenR90_ShouldReturnCorrectly() throws {
image = UIImage.init(namedTest: "background.jpg")
XCTAssertNotNil(image)

let actual = image.rotate(.R90)
XCTAssertNotNil(actual)
XCTAssertEqual(actual.size, CGSize(width: 530, height: 800))
}

func testRotate_WhenR180_ShouldReturnCorrectly() throws {
image = UIImage.init(namedTest: "background.jpg")
XCTAssertNotNil(image)

let actual = image.rotate(.R180)
XCTAssertNotNil(actual)
XCTAssertEqual(actual.size, CGSize(width: 800, height: 530))
}

func testRotate_WhenR270_ShouldReturnCorrectly() throws {
image = UIImage.init(namedTest: "background.jpg")
XCTAssertNotNil(image)

let actual = image.rotate(.R270)
XCTAssertNotNil(actual)
XCTAssertEqual(actual.size, CGSize(width: 530, height: 800))
}

func testRotate_WhenNone_ShouldReturnCorrectly() throws {
image = UIImage.init(namedTest: "background.jpg")
XCTAssertNotNil(image)

let actual = image.rotate(.None)
XCTAssertNotNil(actual)
XCTAssertEqual(actual.size, CGSize(width: 800, height: 530))
}
}

0 comments on commit a82f95e

Please sign in to comment.