Skip to content

Commit

Permalink
task: Make image compression level configurable from flags #2128 (#2129)
Browse files Browse the repository at this point in the history
Default value is: 40% compression down from 60%
  • Loading branch information
priyonto authored Aug 25, 2024
1 parent ced1491 commit a79ced7
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ final class BackgroundSelectionModuleFactoryImpl: BackgroundSelectionModuleFacto
presenter.photoPickerPresenter = r.resolve(PhotoPickerPresenter.self)
presenter.ruuviSensorPropertiesService = r.resolve(RuuviServiceSensorProperties.self)
presenter.ruuviLocalImages = r.resolve(RuuviLocalImages.self)
presenter.settings = r.resolve(RuuviLocalSettings.self)
presenter.errorPresenter = r.resolve(ErrorPresenter.self)
return presenter
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ final class BackgroundSelectionPresenter: BackgroundSelectionModuleInput {
// TODO: Find out why backgroundToken is getting notification twice.
/// A boolean to keep track of background upload for local sensors
private var didUploadBackground: Bool = false
private let maxSize: CGSize = .init(width: 3000, height: 3000)

var photoPickerPresenter: PhotoPickerPresenter! {
didSet {
Expand All @@ -40,6 +41,7 @@ final class BackgroundSelectionPresenter: BackgroundSelectionModuleInput {

var ruuviSensorPropertiesService: RuuviServiceSensorProperties!
var ruuviLocalImages: RuuviLocalImages!
var settings: RuuviLocalSettings!
var errorPresenter: ErrorPresenter!

init(ruuviTag: RuuviTagSensor?) {
Expand Down Expand Up @@ -174,7 +176,9 @@ extension BackgroundSelectionPresenter: PhotoPickerPresenterDelegate {
viewModel.isUploadingBackground.value = true
ruuviSensorPropertiesService.set(
image: photo,
for: ruuviTag
for: ruuviTag,
maxSize: maxSize,
compressionQuality: CGFloat(settings.imageCompressionQuality)*0.1
).on(success: { [weak self] _ in
self?.viewModel.isUploadingBackground.value = false
self?.viewModel.background.value = photo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ extension DefaultsPresenter {
buildChartDurationHours(),
saveAdvertisementsInterval(),
saveHeartbeatsForgroundInterval(),
buildImageCompressionQuality(),
buildAskForReviewFirstTime(),
buildAskForReviewLater(),
buildDashboardCardTapAction(),
Expand Down Expand Up @@ -261,6 +262,20 @@ extension DefaultsPresenter {
return heartbeatsInterval
}

private func buildImageCompressionQuality() -> DefaultsViewModel {
let viewModel = DefaultsViewModel()
viewModel.item.value = .imageCompressionQuality
viewModel.title = RuuviLocalization.Defaults.ImageCompressionQuality.title
viewModel.integer.value = settings.imageCompressionQuality
viewModel.unit = .decimal
viewModel.type.value = .stepper

bind(viewModel.integer, fire: false) { observer, integer in
observer.settings.imageCompressionQuality = integer.bound
}
return viewModel
}

private func saveAdvertisementsInterval() -> DefaultsViewModel {
let advertisementInterval = DefaultsViewModel()
advertisementInterval.title = RuuviLocalization.ForegroundRow.Advertisement.title
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ enum DefaultsType {
case plain
}

enum DefaultItem {
case imageCompressionQuality
case other
}

class DefaultsViewModel: Identifiable {
var id = UUID().uuidString

var title: String?
var type: Observable<DefaultsType?> = .init()
var item: Observable<DefaultItem?> = .init()
// Value for switcher type
var boolean: Observable<Bool?> = .init()
var hideStatusLabel: Observable<Bool?> = .init(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ protocol DefaultsStepperTableViewCellDelegate: AnyObject {
class DefaultsStepperTableViewCell: UITableViewCell {
weak var delegate: DefaultsStepperTableViewCellDelegate?
var unit: DefaultsIntegerUnit = .seconds
var item: DefaultItem?

@IBOutlet var titleLabel: UILabel!
@IBOutlet var stepper: UIStepper!
Expand All @@ -31,11 +32,16 @@ class DefaultsStepperTableViewCell: UITableViewCell {
case .decimal:
""
}
switch unit {
case .hours, .minutes, .seconds:
titleLabel.text = prefix + " " + "(" + "\(result)" + " " + unitString + ")"
case .decimal:
titleLabel.text = prefix + " " + "(" + "\(result)" + ")"
switch item {
case .imageCompressionQuality:
titleLabel.text = prefix + " " + "(" + "\(result)" + "%)"
default:
switch unit {
case .hours, .minutes, .seconds:
titleLabel.text = prefix + " " + "(" + "\(result)" + " " + unitString + ")"
case .decimal:
titleLabel.text = prefix + " " + "(" + "\(result)" + ")"
}
}
delegate?.defaultsStepper(cell: self, didChange: result)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension DefaultsTableViewController {
viewModels.count
}

// swiftlint:disable:next function_body_length
// swiftlint:disable:next function_body_length cyclomatic_complexity
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let viewModel = viewModels[indexPath.row]
switch viewModel.type.value {
Expand Down Expand Up @@ -88,36 +88,48 @@ extension DefaultsTableViewController {
) as! DefaultsStepperTableViewCell
// swiftlint:enable force_cast
let title = viewModel.title ?? ""
let unitString: String
switch viewModel.unit {
case .hours:
unitString = RuuviLocalization.Defaults.Interval.Hour.string
cell.stepper.stepValue = 1
case .minutes:
unitString = RuuviLocalization.Defaults.Interval.Min.string
cell.stepper.stepValue = 5
case .seconds:
unitString = RuuviLocalization.Defaults.Interval.Sec.string
cell.stepper.stepValue = 30
case .decimal:
unitString = ""
cell.stepper.stepValue = 5
cell.stepper.minimumValue = 5
}

cell.unit = viewModel.unit
cell.item = viewModel.item.value
let result = viewModel.integer.value.bound
switch viewModel.unit {
case .hours, .minutes, .seconds:
cell.titleLabel.text = title + " "
+ "(" + "\(result)" + " "
+ unitString + ")"
case .decimal:
cell.titleLabel.text = title + " " + "(" + "\(result)" + ")"
switch viewModel.item.value {
case .imageCompressionQuality:
cell.titleLabel.text = title + " " + "(" + "\(result)" + "%)"
cell.stepper.stepValue = 10
cell.stepper.minimumValue = 10
cell.stepper.maximumValue = 100
cell.stepper.value = Double(viewModel.integer.value.bound)
default:
let unitString: String
switch viewModel.unit {
case .hours:
unitString = RuuviLocalization.Defaults.Interval.Hour.string
cell.stepper.stepValue = 1
case .minutes:
unitString = RuuviLocalization.Defaults.Interval.Min.string
cell.stepper.stepValue = 5
case .seconds:
unitString = RuuviLocalization.Defaults.Interval.Sec.string
cell.stepper.stepValue = 30
case .decimal:
unitString = ""
cell.stepper.stepValue = 5
cell.stepper.minimumValue = 5
}
switch viewModel.unit {
case .hours, .minutes, .seconds:
cell.titleLabel.text = title + " "
+ "(" + "\(result)" + " "
+ unitString + ")"
case .decimal:
cell.titleLabel.text = title + " " + "(" + "\(result)" + ")"
}
cell.stepper.value = Double(viewModel.integer.value.bound)
}

cell.titleLabel.textColor = RuuviColor.menuTextColor.color
cell.stepper.backgroundColor = RuuviColor.tintColor.color
cell.prefix = title
cell.stepper.value = Double(viewModel.integer.value.bound)
cell.delegate = self
return cell
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public protocol RuuviLocalSettings {
var showSwitchStatusLabel: Bool { get set }
var showAlertsRangeInGraph: Bool { get set }
var useNewGraphRendering: Bool { get set }
var imageCompressionQuality: Int { get set }

/// Syncs full history for all sensoers after code verification
/// on sign in, before presenting dashboard. Heavy after sign in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,9 @@ final class RuuviLocalSettingsUserDefaults: RuuviLocalSettings {
var showAlertsRangeInGraph: Bool
@UserDefault("SettingsUserDefaults.useNewGraphRendering", defaultValue: false)
var useNewGraphRendering: Bool
// On a scale of 10-100, 100 being best quality, and 10 being the worst.
@UserDefault("SettingsUserDefaults.imageCompressionQuality", defaultValue: 40)
var imageCompressionQuality: Int

@UserDefault("SettingsUserDefaults.historySyncLegacy", defaultValue: false)
var historySyncLegacy: Bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public protocol RuuviServiceSensorProperties {
image: UIImage,
for sensor: RuuviTagSensor,
progress: ((MACIdentifier, Double) -> Void)?,
maxSize: CGSize
maxSize: CGSize,
compressionQuality: CGFloat
) -> Future<URL, RuuviServiceError>

@discardableResult
Expand All @@ -29,13 +30,16 @@ public protocol RuuviServiceSensorProperties {
public extension RuuviServiceSensorProperties {
func set(
image: UIImage,
for sensor: RuuviTagSensor
for sensor: RuuviTagSensor,
maxSize: CGSize,
compressionQuality: CGFloat
) -> Future<URL, RuuviServiceError> {
set(
image: image,
for: sensor,
progress: nil,
maxSize: CGSize(width: 3000, height: 3000)
maxSize: maxSize,
compressionQuality: compressionQuality
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ public final class RuuviServiceSensorPropertiesImpl: RuuviServiceSensorPropertie
image: UIImage,
for sensor: RuuviTagSensor,
progress: ((MACIdentifier, Double) -> Void)?,
maxSize: CGSize
maxSize: CGSize,
compressionQuality: CGFloat
) -> Future<URL, RuuviServiceError> {
let promise = Promise<URL, RuuviServiceError>()
let croppedImage = coreImage.cropped(image: image, to: maxSize)
guard let jpegData = croppedImage.jpegData(compressionQuality: 0.6)
guard let jpegData = croppedImage.jpegData(compressionQuality: compressionQuality)
else {
promise.fail(error: .failedToGetJpegRepresentation)
return promise.future
Expand Down
2 changes: 1 addition & 1 deletion station.localization

0 comments on commit a79ced7

Please sign in to comment.