Skip to content

Commit

Permalink
Merge pull request #38 from AkkeyLab/feature/pixel-box-size
Browse files Browse the repository at this point in the history
🆕 Add PixelBoxSize parameter
  • Loading branch information
AkkeyLab authored Oct 18, 2019
2 parents 9654b86 + 37e450d commit 45f186c
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 32 deletions.
223 changes: 204 additions & 19 deletions RxScreenProtectKitExample/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

80 changes: 76 additions & 4 deletions RxScreenProtectKitExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import RxScreenProtectKit
import RxSwift
import UIKit

final class ViewController: UIViewController {
final class FirstViewController: UIViewController {
// https://www.pakutaso.com
@IBOutlet private weak var mainImageView: UIImageView!
@IBOutlet private weak var nameLabel: UILabel!
Expand Down Expand Up @@ -56,7 +56,6 @@ final class ViewController: UIViewController {
func changeSettings() {
let filterCase: [CALayerContentsFilter] = [.linear, .nearest, .trilinear]
minificationFilterControl.rx.value
.skip(1)
.subscribe(onNext: { [weak self] index in
guard let self = self else { return }
ScreenProtectKit
Expand All @@ -67,7 +66,6 @@ final class ViewController: UIViewController {
})
.disposed(by: bag)
magnificationFilterControl.rx.value
.skip(1)
.subscribe(onNext: { [weak self] index in
guard let self = self else { return }
ScreenProtectKit
Expand All @@ -78,7 +76,6 @@ final class ViewController: UIViewController {
})
.disposed(by: bag)
scaleChanger.rx.value
.skip(1)
.subscribe(onNext: { [weak self] value in
guard let self = self else { return }
ScreenProtectKit
Expand All @@ -91,3 +88,78 @@ final class ViewController: UIViewController {
.disposed(by: bag)
}
}

final class SecondViewController: UIViewController {
@IBOutlet private weak var bigImageView: UIImageView!
@IBOutlet private weak var normalImageView: UIImageView!
@IBOutlet private weak var shortImageView: UIImageView!
@IBOutlet private weak var minificationFilterControl: UISegmentedControl!
@IBOutlet private weak var magnificationFilterControl: UISegmentedControl!
@IBOutlet private weak var pixelBoxSizeChanger: UISlider!
@IBOutlet private weak var applyButton: UIButton!
@IBOutlet private weak var pixelBoxSizeLabel: UILabel!
@IBOutlet private weak var validSwitch: UISwitch!
private let bag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()
self.rx.isScreenRecord
.bind(to: bigImageView.layer.rx.isMosaic)
.disposed(by: bag)
self.rx.isScreenRecord
.bind(to: normalImageView.layer.rx.isMosaic)
.disposed(by: bag)
self.rx.isScreenRecord
.bind(to: shortImageView.layer.rx.isMosaic)
.disposed(by: bag)
applyButton.rx.tap
.subscribe(onNext: { [weak self] in
self?.bigImageView.layer.applyMosaic()
self?.normalImageView.layer.applyMosaic()
self?.shortImageView.layer.applyMosaic()
})
.disposed(by: bag)
validSwitch.rx.value
.subscribe(onNext: { isValid in
ScreenProtectKit.shared.isValid = isValid
})
.disposed(by: bag)

changeSettings()
}

func changeSettings() {
let filterCase: [CALayerContentsFilter] = [.linear, .nearest, .trilinear]
minificationFilterControl.rx.value
.subscribe(onNext: { [weak self] index in
guard let self = self else { return }
ScreenProtectKit
.shared
.config(pixelBoxSize: CGFloat(self.pixelBoxSizeChanger.value),
minificationFilter: filterCase[index],
magnificationFilter: filterCase[self.magnificationFilterControl.selectedSegmentIndex])
})
.disposed(by: bag)
magnificationFilterControl.rx.value
.subscribe(onNext: { [weak self] index in
guard let self = self else { return }
ScreenProtectKit
.shared
.config(pixelBoxSize: CGFloat(self.pixelBoxSizeChanger.value),
minificationFilter: filterCase[self.minificationFilterControl.selectedSegmentIndex],
magnificationFilter: filterCase[index])
})
.disposed(by: bag)
pixelBoxSizeChanger.rx.value
.subscribe(onNext: { [weak self] value in
guard let self = self else { return }
ScreenProtectKit
.shared
.config(pixelBoxSize: CGFloat(self.pixelBoxSizeChanger.value),
minificationFilter: filterCase[self.minificationFilterControl.selectedSegmentIndex],
magnificationFilter: filterCase[self.magnificationFilterControl.selectedSegmentIndex])
self.pixelBoxSizeLabel.text = "\(value)"
})
.disposed(by: bag)
}
}
18 changes: 15 additions & 3 deletions RxScreenProtectKitTests/RxScreenProtectKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import XCTest
final class RxScreenProtectKitTests: XCTestCase {

func testMosaicType() {
let type = MosaicType(isValid: true)
let type = MosaicType(isValid: true, rasterizationScale: 0.1, pixelBoxSize: 0)
XCTAssertEqual(type.minificationFilter, .trilinear)
XCTAssertEqual(type.rasterizationScale, 0.1)
}

func testValidAttachMosaic() {
let layer = CALayer()
layer.attachMosaic(type: MosaicType(isValid: true))
layer.attachMosaic(type: MosaicType(isValid: true, rasterizationScale: 0.1, pixelBoxSize: 0))
XCTAssertEqual(layer.minificationFilter, .trilinear)
XCTAssertEqual(layer.magnificationFilter, .nearest)
XCTAssertEqual(layer.rasterizationScale, 0.1)
Expand All @@ -29,7 +29,7 @@ final class RxScreenProtectKitTests: XCTestCase {

func testInvalidAttachMosaic() {
let layer = CALayer()
layer.attachMosaic(type: MosaicType(isValid: false))
layer.attachMosaic(type: MosaicType(isValid: false, rasterizationScale: 0.1, pixelBoxSize: 0))
XCTAssertEqual(layer.minificationFilter, .linear)
XCTAssertEqual(layer.magnificationFilter, .linear)
XCTAssertEqual(layer.rasterizationScale, 1.0)
Expand Down Expand Up @@ -194,5 +194,17 @@ final class RxScreenProtectKitTests: XCTestCase {
label.protectText = "protect"
XCTAssertEqual(label.text, "original")
}

func testPixelBoxSize() {
let layer = CALayer()
layer.frame = CGRect(x: 0, y: 0, width: 150, height: 50)
layer.attachMosaic(type: MosaicType(isValid: true, rasterizationScale: 0.1, pixelBoxSize: 5))
XCTAssertEqual(layer.minificationFilter, .trilinear)
XCTAssertEqual(layer.magnificationFilter, .nearest)
XCTAssertEqual(layer.rasterizationScale, 0.05)
XCTAssertEqual(layer.shouldRasterize, true)
layer.attachMosaic(type: MosaicType(isValid: true, rasterizationScale: 0.1, pixelBoxSize: 10))
XCTAssertEqual(layer.rasterizationScale, 0.1)
}
// swiftlint:enable force_try
}
24 changes: 18 additions & 6 deletions Source/Extensions/CALayer+Mosaic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ struct MosaicType {
var isValid: Bool
/// The scale at which to rasterize content, relative to the coordinate space of the layer.
var rasterizationScale: CGFloat
/// When compressing an image, specify the number of pixels to be compressed to one pixel.
var pixelBoxSize: CGFloat
/// The filter used when reducing the size of the content.
var minificationFilter: CALayerContentsFilter
/// The filter used when increasing the size of the content.
Expand All @@ -24,17 +26,21 @@ struct MosaicType {
This type indicates a mosaic.

- parameters:
- isValid: This flag indicates the presence or absence of a mosaic.
- rasterizationScale: The scale at which to rasterize content, relative to the coordinate space of the layer.
- minificationFilter: The filter used when reducing the size of the content.
- magnificationFilter: The filter used when increasing the size of the content.
- isValid: This flag indicates the presence or absence of a mosaic.
- rasterizationScale: The scale at which to rasterize content, relative to the coordinate space of the layer.
- pixelBoxSize: When compressing an image, specify the number of pixels to be compressed to one pixel.
If this is non-zero, `rasterizationScale` will be ignored.
- minificationFilter: The filter used when reducing the size of the content.
- magnificationFilter: The filter used when increasing the size of the content.
*/
init (isValid: Bool,
rasterizationScale: CGFloat = 0.1,
rasterizationScale: CGFloat,
pixelBoxSize: CGFloat,
minificationFilter: CALayerContentsFilter = .trilinear,
magnificationFilter: CALayerContentsFilter = .nearest) {
self.isValid = isValid
self.rasterizationScale = rasterizationScale
self.pixelBoxSize = pixelBoxSize
self.minificationFilter = minificationFilter
self.magnificationFilter = magnificationFilter
}
Expand All @@ -48,8 +54,13 @@ extension CALayer {
- type: This type indicates a mosaic.
*/
func attachMosaic(type: MosaicType) {
let absoluteScale = (2 * type.pixelBoxSize) / (bounds.height + bounds.width)
if absoluteScale == 0 || absoluteScale.isNaN {
rasterizationScale = type.isValid ? type.rasterizationScale : 1.0
} else {
rasterizationScale = absoluteScale
}
shouldRasterize = type.isValid
rasterizationScale = type.isValid ? type.rasterizationScale : 1.0
minificationFilter = type.isValid ? type.minificationFilter : .linear
magnificationFilter = type.isValid ? type.magnificationFilter : .linear
}
Expand All @@ -59,6 +70,7 @@ extension CALayer {
public func applyMosaic(kit: ScreenProtectKit = .shared) {
attachMosaic(type: .init(isValid: shouldRasterize,
rasterizationScale: kit.rasterizationScale,
pixelBoxSize: kit.pixelBoxSize,
minificationFilter: kit.minificationFilter,
magnificationFilter: kit.magnificationFilter)
)
Expand Down
1 change: 1 addition & 0 deletions Source/Extensions/CALayer+Rx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public extension Reactive where Base: CALayer {
let kit = ScreenProtectKit.shared
layer.attachMosaic(type: .init(isValid: isValid,
rasterizationScale: kit.rasterizationScale,
pixelBoxSize: kit.pixelBoxSize,
minificationFilter: kit.minificationFilter,
magnificationFilter: kit.magnificationFilter)
)
Expand Down
5 changes: 5 additions & 0 deletions Source/ScreenProtectKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public final class ScreenProtectKit {
public static let shared = ScreenProtectKit()

internal var rasterizationScale: CGFloat = 0.1
internal var pixelBoxSize: CGFloat = 0
internal var minificationFilter: CALayerContentsFilter = .trilinear
internal var magnificationFilter: CALayerContentsFilter = .nearest
internal lazy var isValidState = _isValid.distinctUntilChanged()
Expand All @@ -41,13 +42,17 @@ public final class ScreenProtectKit {

- parameters:
- rasterizationScale: The scale at which to rasterize content, relative to the coordinate space of the layer.
- pixelBoxSize: When compressing an image, specify the number of pixels to be compressed to one pixel.
If this is non-zero, `rasterizationScale` will be ignored.
- minificationFilter: The filter used when reducing the size of the content.
- magnificationFilter: The filter used when increasing the size of the content.
*/
public func config(rasterizationScale: CGFloat = 0.1,
pixelBoxSize: CGFloat = 0,
minificationFilter: CALayerContentsFilter = .trilinear,
magnificationFilter: CALayerContentsFilter = .nearest) {
self.rasterizationScale = rasterizationScale
self.pixelBoxSize = pixelBoxSize
self.minificationFilter = minificationFilter
self.magnificationFilter = magnificationFilter
}
Expand Down

0 comments on commit 45f186c

Please sign in to comment.