diff --git a/thirdparty/flutter_image_compress b/thirdparty/flutter_image_compress deleted file mode 160000 index f130a414e..000000000 --- a/thirdparty/flutter_image_compress +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f130a414e345fb54f24a69e29a9a02afc8ad38ac diff --git a/thirdparty/flutter_image_compress/.gitattributes b/thirdparty/flutter_image_compress/.gitattributes new file mode 100644 index 000000000..3dcab1e39 --- /dev/null +++ b/thirdparty/flutter_image_compress/.gitattributes @@ -0,0 +1,3 @@ +*.dart linguist-language=Dart +*.m linguist-language=Dart +*.h linguist-language=Dart diff --git a/thirdparty/flutter_image_compress/.gitignore b/thirdparty/flutter_image_compress/.gitignore new file mode 100644 index 000000000..a93768b25 --- /dev/null +++ b/thirdparty/flutter_image_compress/.gitignore @@ -0,0 +1,12 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ +pubspec.lock + +build/ +.idea/ +.flutter-plugins-dependencies +.vscode/settings.json +flutter_export_environment.sh diff --git a/thirdparty/flutter_image_compress/.vscode/launch.json b/thirdparty/flutter_image_compress/.vscode/launch.json new file mode 100644 index 000000000..4e9612bd3 --- /dev/null +++ b/thirdparty/flutter_image_compress/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Flutter", + "request": "launch", + "type": "dart", + "program": "example/lib/main.dart" + } + ] +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/CHANGELOG.md b/thirdparty/flutter_image_compress/CHANGELOG.md new file mode 100644 index 000000000..578e7b50d --- /dev/null +++ b/thirdparty/flutter_image_compress/CHANGELOG.md @@ -0,0 +1,164 @@ +# CHANGELOG + +## 0.7.0 + +- Fix + + - Fix momory leaked for android. + +- Support android v2 plugin. + +**Breaking Change**: + +- Replace `List` to `Uint8List`. + +## 0.6.8 + +Update `Validate` code. + +## 0.6.7 + +Use the async GCD in iOS. + +## 0.6.6 + +[#116](https://github.com/OpenFlutter/flutter_image_compress/pull/116), [#124](https://github.com/OpenFlutter/flutter_image_compress/pull/124) + +## 0.6.5+1 + +Fix: + +- Web format error +- Import header error for iOS. + +## 0.6.5 + +New feature + +- Support webp on iOS. + +## 0.6.4 + +New feature: + +- Add Params inSampleSize for methods. +- Heif and webp Partially supported. + +## 0.6.3 + +Fix: + +- Android: When the register of the calling plugin is not in the main process or there is no Activity. + +## 0.6.2 + +Optimization: + +- Reduce the speed required for ios to add dependencies by copying the `SYPictureMetadata` source code into the project. + +## 0.6.1 + +Fix: + +- autoCorrectionAngle switches image width and height. + +New feature: + +- Keep exif (no have orientation), use `keepExif` + +## 0.6.0 + +**BREAKING CHANGE** : + +- remove method `getImageInfo`. + +For the time being, the follow-dev branch is no longer used, but only the master branch is needed to unify the pub version number. + +New Feature: + +- It is now supported to set the compression target to png format. + +## 0.5.2 + +Fix: + +- [#49](https://github.com/OpenFlutter/flutter_image_compress/issues/49): A problem of reading Exif information. + +## 0.5.1 + +Change `reportError` with flutter stable version. + +**Breaking Change:** +The autoCorrectionAngle parameter causes a number of situations to behave differently than `0.4.0`. See readme for details. + +## 0.5.0 + +(don't use) + +**Breaking Change:** +Because `FlutterError.reportError` method's param `context` type changed. +So this library will add the constraints of flutter SDK so that users before 1.5.9 will not use version 0.5.0 incorrectly. + +## 0.4.0 + +Some code has been added to ensure that parameters that do not pass in native do not trigger crash. + +## 0.3.1 + +Fix: + +- Android close file output stream. + +## 0.3.0 + +Fix: + +- optimize compress scale. + +## 0.2.4 + +Updated Kotlin version + +**Breaking change**. Migrate from the deprecated original Android Support +Library to AndroidX. This shouldn't result in any functional changes, but it +requires any Android apps using this plugin to [also +migrate](https://developer.android.com/jetpack/androidx/migrate) if they're +using the original support library. + +## 0.2.3 + +change iOS return type + +## 0.2.2 + +add some dart doc + +## 0.2.1 + +update readme + +## 0.2.0 + +The version number is updated so that people who can use the higher version of gradle can use it. see pr #8 + +if android run error, you must update your kotlin'version to 1.2.71+ + +## 0.1.4 + +add optional params rotate + +fix bug + +update example + +## 0.1.3 + +fix the ios `flutter.h` bug + +## 0.1.1 + +update readme + +## 0.1.0 + +first version diff --git a/thirdparty/flutter_image_compress/CONTRIBUTING.md b/thirdparty/flutter_image_compress/CONTRIBUTING.md new file mode 100644 index 000000000..6c2e2082b --- /dev/null +++ b/thirdparty/flutter_image_compress/CONTRIBUTING.md @@ -0,0 +1,5 @@ +# CONTRIBUTING + +Please submit changes to master branch. + +And make sure your code is willing to comply with MIT style. diff --git a/thirdparty/flutter_image_compress/LICENSE b/thirdparty/flutter_image_compress/LICENSE new file mode 100644 index 000000000..2dc7fbcb3 --- /dev/null +++ b/thirdparty/flutter_image_compress/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 caijinglong + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/thirdparty/flutter_image_compress/README.md b/thirdparty/flutter_image_compress/README.md new file mode 100644 index 000000000..beb4d21cf --- /dev/null +++ b/thirdparty/flutter_image_compress/README.md @@ -0,0 +1,351 @@ +# flutter_image_compress + +[![ImageCompress](https://img.shields.io/badge/OpenFlutter-ImageCompress-blue.svg)](https://github.com/OpenFlutter/flutter_image_compress) +[![pub package](https://img.shields.io/pub/v/flutter_image_compress.svg)](https://pub.dartlang.org/packages/flutter_image_compress) +![GitHub](https://img.shields.io/github/license/OpenFlutter/flutter_image_compress.svg) +[![GitHub stars](https://img.shields.io/github/stars/OpenFlutter/flutter_image_compress.svg?style=social&label=Stars)](https://github.com/OpenFlutter/flutter_image_compress) +[![Awesome](https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square)](https://stackoverflow.com/questions/tagged/flutter?sort=votes) + +Compresses image as native plugin (Obj-C/Kotlin) + +This library can works on Android and iOS. + +- [flutter_image_compress](#flutter_image_compress) + - [Why don't you use dart to do it](#why-dont-you-use-dart-to-do-it) + - [Usage](#usage) + - [About common params](#about-common-params) + - [minWidth and minHeight](#minwidth-and-minheight) + - [rotate](#rotate) + - [autoCorrectionAngle](#autocorrectionangle) + - [quality](#quality) + - [format](#format) + - [Webp](#webp) + - [HEIF(Heic)](#heifheic) + - [Heif for iOS](#heif-for-ios) + - [Heif for Android](#heif-for-android) + - [inSampleSize](#insamplesize) + - [keepExif](#keepexif) + - [Result](#result) + - [About `List` and `Uint8List`](#about-listint-and-uint8list) + - [Runtime Error](#runtime-error) + - [Android](#android) + - [iOS](#ios) + - [Troubleshooting or common error](#troubleshooting-or-common-error) + - [Compressing returns `null`](#compressing-returns-null) + - [Android build error](#android-build-error) + - [About EXIF information](#about-exif-information) + - [LICENSE](#license) + - [PNG/JPEG encoder](#pngjpeg-encoder) + - [Webp encoder](#webp-encoder) + - [HEIF encoder](#heif-encoder) + - [About Exif handle code](#about-exif-handle-code) + +## Why don't you use dart to do it + +Q:Dart already has image compression libraries. Why use native? + +A:For unknown reasons, image compression in Dart language is not efficient, even in release version. Using isolate does not solve the problem. + +## Usage + +```yaml +dependencies: + flutter_image_compress: ^0.7.0 +``` + +```dart +import 'package:flutter_image_compress/flutter_image_compress.dart'; +``` + +Use as: + +[See full example](https://github.com/OpenFlutter/flutter_image_compress/blob/master/example/lib/main.dart) + +There are several ways to use the library api. + +```dart + + // 1. compress file and get Uint8List + Future testCompressFile(File file) async { + var result = await FlutterImageCompress.compressWithFile( + file.absolute.path, + minWidth: 2300, + minHeight: 1500, + quality: 94, + rotate: 90, + ); + print(file.lengthSync()); + print(result.length); + return result; + } + + // 2. compress file and get file. + Future testCompressAndGetFile(File file, String targetPath) async { + var result = await FlutterImageCompress.compressAndGetFile( + file.absolute.path, targetPath, + quality: 88, + rotate: 180, + ); + + print(file.lengthSync()); + print(result.lengthSync()); + + return result; + } + + // 3. compress asset and get Uint8List. + Future testCompressAsset(String assetName) async { + var list = await FlutterImageCompress.compressAssetImage( + assetName, + minHeight: 1920, + minWidth: 1080, + quality: 96, + rotate: 180, + ); + + return list; + } + + // 4. compress Uint8List and get another Uint8List. + Future testComporessList(Uint8List list) async { + var result = await FlutterImageCompress.compressWithList( + list, + minHeight: 1920, + minWidth: 1080, + quality: 96, + rotate: 135, + ); + print(list.length); + print(result.length); + return result; + } +``` + +## About common params + +### minWidth and minHeight + +`minWidth` and `minHeight` are constraints on image scaling. + +For example, a 4000\*2000 image, `minWidth` set to 1920, `minHeight` set to 1080, the calculation is as follows: + +```dart +// Using dart as an example, the actual implementation is Kotlin or OC. +import 'dart:math' as math; + +void main() { + var scale = calcScale( + srcWidth: 4000, + srcHeight: 2000, + minWidth: 1920, + minHeight: 1080, + ); + + print("scale = $scale"); // scale = 1.8518518518518519 + print("target width = ${4000 / scale}, height = ${2000 / scale}"); // target width = 2160.0, height = 1080.0 +} + +double calcScale({ + double srcWidth, + double srcHeight, + double minWidth, + double minHeight, +}) { + var scaleW = srcWidth / minWidth; + var scaleH = srcHeight / minHeight; + + var scale = math.max(1.0, math.min(scaleW, scaleH)); + + return scale; +} + +``` + +If your image width is smaller than minWidth or height samller than minHeight, scale will be 1, that is, the size will not change. + +### rotate + +If you need to rotate the picture, use this parameter. + +### autoCorrectionAngle + +This property only exists in the version after 0.5.0. + +And for historical reasons, there may be conflicts with rotate attributes, which need to be self-corrected. + +Modify rotate to 0 or autoCorrectionAngle to false. + +### quality + +Quality of target image. + +If `format` is png, the param will be ignored in iOS. + +### format + +Supports jpeg or png, default is jpeg. + +The format class sign `enum CompressFormat`. + +Heif and webp Partially supported. + +#### Webp + +Support android by the system api (speed very nice). + +And support iOS, but However, no system implementation, using [third-party libraries](https://github.com/SDWebImage/SDWebImageWebPCoder) used, it is not recommended due to encoding speed. In the future, libwebp by google (c / c ++) may be used to do coding work, bypassing other three-party libraries, but there is no guarantee of implementation time. + +#### HEIF(Heic) + +##### Heif for iOS + +Only support iOS 11+. + +##### Heif for Android + +Use https://developer.android.com/reference/androidx/heifwriter/HeifWriter.html to implemation. + +Only support API 28+. + +And may require hardware encoder support, does not guarantee that all devices above API28 are available + +### inSampleSize + +The param is only support android. + +For a description of this parameter, see the [Android official website](https://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize). + +### keepExif + +If this parameter is true, EXIF information is saved in the compressed result. + +Attention should be paid to the following points: + +1. Default value is false. +2. Even if set to true, the direction attribute is not included. +3. Only support jpg format, PNG format does not support. + +## Result + +The result of returning a List collection will not have null, but will always be an empty array. + +The returned file may be null. In addition, please decide for yourself whether the file exists. + +### About `List` and `Uint8List` + +You may need to convert `List` to `Uint8List` to display images. + +To use `Uint8List`, you need import package to your code like this: + +![img](https://raw.githubusercontent.com/CaiJingLong/asset_for_picgo/master/20190519111735.png) + +```dart +final image = Uint8List.fromList(imageList) +ImageProvider provider = MemoryImage(Uint8List.fromList(imageList)); +``` + +Usage in `Image` Widget: + +```dart +List image = await testCompressFile(file); +ImageProvider provider = MemoryImage(Uint8List.fromList(image)); + +Image( + image: provider ?? AssetImage("img/img.jpg"), +), +``` + +Write to file usage: + +```dart +void writeToFile(List image, String filePath) { + final file = File(filePath); + file.writeAsBytes(image, flush: true, mode: FileMode.write); +} +``` + +## Runtime Error + +Because of some support issues, all APIs will be compatible with format and system compatibility, and an exception (UnsupportError) may be thrown, so if you insist on using webp and heic formats, please catch the exception yourself and use it on unsupported devices jpeg compression. + +Example: + +```dart +Future compressAndTryCatch(String path) async { + Uint8List result; + try { + result = await FlutterImageCompress.compressWithFile(path, + format: CompressFormat.heic); + } on UnsupportedError catch (e) { + print(e); + result = await FlutterImageCompress.compressWithFile(path, + format: CompressFormat.jpeg); + } + return result; + } +``` + +## Android + +You may need to update Kotlin to version `1.3.72` or higher. + +## iOS + +No problems currently found. + +## Troubleshooting or common error + +### Compressing returns `null` + +Sometimes, compressing will return null. You should check if you can read/write the file, and the parent folder of the target file must exist. + +For example, use the [path_provider](https://pub.dartlang.org/packages/path_provide) plugin to access some application folders, and use a permission plugin to request permission to access SD cards on Android/iOS. + +### Android build error + +```groovy +Caused by: org.gradle.internal.event.ListenerNotificationException: Failed to notify project evaluation listener. + at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:86) + ... +Caused by: java.lang.AbstractMethodError + at org.jetbrains.kotlin.gradle.plugin.KotlinPluginKt.resolveSubpluginArtifacts(KotlinPlugin.kt:776) + ... +``` + +See [flutter/flutter/issues#21473](https://github.com/flutter/flutter/issues/21473#issuecomment-420434339) + +You need to upgrade your Kotlin version to `1.2.71+`(recommended 1.3.72). + +If Flutter supports more platforms (Windows, Mac, Linux, etc) in the future and you use this library, propose an issue or PR! + +## About EXIF information + +Using this library, EXIF information will be removed by default. + +EXIF information can be retained by setting keepExif to true, but not `direction` information. + +## LICENSE + +The code under MIT style. + +### PNG/JPEG encoder + +Each using system API. + +### Webp encoder + +Use [SDWebImageWebPCoder](https://github.com/SDWebImage/SDWebImageWebPCoder) to encode the UIImage in iOS. (Under MIT) + +Android code use the Android system api. + +### HEIF encoder + +Use iOS system api in iOS. + +Use [HeifWriter(androidx component by Google)](https://developer.android.google.cn/jetpack/androidx/releases/heifwriter) to encode in androidP or higher. + +### About Exif handle code + +The iOS code was copied from [dvkch/SYPictureMetadata](https://github.com/dvkch/SYPictureMetadata), [LICENSE](https://github.com/dvkch/SYPictureMetadata/blob/master/LICENSE.md) + +The android code was copied from flutter/plugin/image_picker and edit some. (BSD 3 style) diff --git a/thirdparty/flutter_image_compress/android/.gitignore b/thirdparty/flutter_image_compress/android/.gitignore new file mode 100644 index 000000000..9a109821b --- /dev/null +++ b/thirdparty/flutter_image_compress/android/.gitignore @@ -0,0 +1,13 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures + + +.settings +.classpath +.project \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/build.gradle b/thirdparty/flutter_image_compress/android/build.gradle new file mode 100644 index 000000000..8236f6743 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/build.gradle @@ -0,0 +1,48 @@ +group 'com.example.flutterimagecompress' +version '1.0-SNAPSHOT' + +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 29 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + defaultConfig { + minSdkVersion 16 + targetSdkVersion 29 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } +} + + +dependencies { + implementation 'androidx.exifinterface:exifinterface:1.1.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'commons-io:commons-io:2.6' + implementation group: 'androidx.heifwriter', name: 'heifwriter', version: '1.0.0' +} diff --git a/thirdparty/flutter_image_compress/android/gradle.properties b/thirdparty/flutter_image_compress/android/gradle.properties new file mode 100644 index 000000000..8bd86f680 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/thirdparty/flutter_image_compress/android/gradle/wrapper/gradle-wrapper.jar b/thirdparty/flutter_image_compress/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..f6b961fd5 Binary files /dev/null and b/thirdparty/flutter_image_compress/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/thirdparty/flutter_image_compress/android/gradle/wrapper/gradle-wrapper.properties b/thirdparty/flutter_image_compress/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..56ed0d862 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun Jun 07 22:31:28 IST 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/thirdparty/flutter_image_compress/android/gradlew b/thirdparty/flutter_image_compress/android/gradlew new file mode 100644 index 000000000..cccdd3d51 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/thirdparty/flutter_image_compress/android/gradlew.bat b/thirdparty/flutter_image_compress/android/gradlew.bat new file mode 100644 index 000000000..f9553162f --- /dev/null +++ b/thirdparty/flutter_image_compress/android/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/thirdparty/flutter_image_compress/android/settings.gradle b/thirdparty/flutter_image_compress/android/settings.gradle new file mode 100644 index 000000000..d919ecae2 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'flutter_image_compress' diff --git a/thirdparty/flutter_image_compress/android/src/main/AndroidManifest.xml b/thirdparty/flutter_image_compress/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000..33f3e572f --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/FlutterImageCompressPlugin.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/FlutterImageCompressPlugin.kt new file mode 100644 index 000000000..7cf50920c --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/FlutterImageCompressPlugin.kt @@ -0,0 +1,69 @@ +package com.example.flutterimagecompress + +import android.content.Context +import android.os.Build +import com.example.flutterimagecompress.core.CompressFileHandler +import com.example.flutterimagecompress.core.CompressListHandler +import com.example.flutterimagecompress.format.FormatRegister +import com.example.flutterimagecompress.handle.common.CommonHandler +import com.example.flutterimagecompress.handle.heif.HeifHandler +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result +import io.flutter.plugin.common.PluginRegistry.Registrar + +class FlutterImageCompressPlugin : FlutterPlugin, MethodCallHandler { + + private lateinit var context: Context + var channel: MethodChannel? = null + + companion object { + @JvmStatic + fun registerWith(registrar: Registrar): Unit { + val plugin = FlutterImageCompressPlugin() + plugin.channel = MethodChannel(registrar.messenger(), "flutter_image_compress") + plugin.context = registrar.context() + plugin.channel?.setMethodCallHandler(plugin) + } + + var showLog = false + } + + init { + FormatRegister.registerFormat(CommonHandler(0)) // jpeg + FormatRegister.registerFormat(CommonHandler(1)) // png + FormatRegister.registerFormat(HeifHandler()) // heic / heif + FormatRegister.registerFormat(CommonHandler(3)) // webp + } + + override fun onMethodCall(call: MethodCall, result: Result): Unit { + when (call.method) { + "showLog" -> result.success(handleLog(call)) + "compressWithList" -> CompressListHandler(call, result).handle(context) + "compressWithFile" -> CompressFileHandler(call, result).handle(context) + "compressWithFileAndGetFile" -> CompressFileHandler(call, result).handleGetFile(context) + "getSystemVersion" -> result.success(Build.VERSION.SDK_INT) + else -> result.notImplemented() + } + } + + private fun handleLog(call: MethodCall): Int { + val arg = call.arguments() + showLog = (arg == true) + return 1 + } + + override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { + this.context = binding.applicationContext + channel = MethodChannel(binding.binaryMessenger, "flutter_image_compress") + channel?.setMethodCallHandler(this) + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + channel?.setMethodCallHandler(null) + channel = null + } + +} diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/CompressFileHandler.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/CompressFileHandler.kt new file mode 100644 index 000000000..5bd97c4e2 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/CompressFileHandler.kt @@ -0,0 +1,117 @@ +package com.example.flutterimagecompress.core + +import android.content.Context +import com.example.flutterimagecompress.FlutterImageCompressPlugin +import com.example.flutterimagecompress.exif.Exif +import com.example.flutterimagecompress.format.FormatRegister +import com.example.flutterimagecompress.logger.log +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.OutputStream + +class CompressFileHandler(private val call: MethodCall, result: MethodChannel.Result) : ResultHandler(result) { + + fun handle(context: Context) { + threadPool.execute { + @Suppress("UNCHECKED_CAST") val args: List = call.arguments as List + val filePath = args[0] as String + var minWidth = args[1] as Int + var minHeight = args[2] as Int + val quality = args[3] as Int + val rotate = args[4] as Int + val autoCorrectionAngle = args[5] as Boolean + val format = args[6] as Int + val keepExif = args[7] as Boolean + val inSampleSize = args[8] as Int + + val formatHandler = FormatRegister.findFormat(format) + + if (formatHandler == null) { + log("No support format.") + reply(null) + return@execute + } + + val exifRotate = + if (autoCorrectionAngle) { + val bytes = File(filePath).readBytes() + Exif.getRotationDegrees(bytes) + } else { + 0 + } + + if (exifRotate == 270 || exifRotate == 90) { + val tmp = minWidth + minWidth = minHeight + minHeight = tmp + } + val targetRotate = rotate + exifRotate + val outputStream = ByteArrayOutputStream() + try { + formatHandler.handleFile(context, filePath, outputStream, minWidth, minHeight, quality, targetRotate, keepExif, inSampleSize) + reply(outputStream.toByteArray()) + } catch (e: Exception) { + if (FlutterImageCompressPlugin.showLog) e.printStackTrace() + reply(null) + } finally { + outputStream.close() + } + } + } + + fun handleGetFile(context: Context) { + threadPool.execute { + @Suppress("UNCHECKED_CAST") val args: List = call.arguments as List + val file = args[0] as String + var minWidth = args[1] as Int + var minHeight = args[2] as Int + val quality = args[3] as Int + val targetPath = args[4] as String + val rotate = args[5] as Int + val autoCorrectionAngle = args[6] as Boolean + + val exifRotate = + if (autoCorrectionAngle) { + val bytes = File(file).readBytes() + Exif.getRotationDegrees(bytes) + } else { + 0 + } + + + val format = args[7] as Int + val keepExif = args[8] as Boolean + val inSampleSize = args[9] as Int + + val formatHandler = FormatRegister.findFormat(format) + + if (formatHandler == null) { + log("No support format.") + reply(null) + return@execute + } + + if (exifRotate == 270 || exifRotate == 90) { + val tmp = minWidth + minWidth = minHeight + minHeight = tmp + } + + val targetRotate = rotate + exifRotate + var outputStream: OutputStream? = null + try { + outputStream = File(targetPath).outputStream() + formatHandler.handleFile(context, file, outputStream, minWidth, minHeight, quality, targetRotate, keepExif, inSampleSize) + reply(targetPath) + } catch (e: Exception) { + if (FlutterImageCompressPlugin.showLog) e.printStackTrace() + reply(null) + } finally { + outputStream?.close() + } + } + } + +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/CompressListHandler.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/CompressListHandler.kt new file mode 100644 index 000000000..31a61f746 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/CompressListHandler.kt @@ -0,0 +1,65 @@ +package com.example.flutterimagecompress.core + +import android.content.Context +import com.example.flutterimagecompress.FlutterImageCompressPlugin +import com.example.flutterimagecompress.exception.CompressError +import com.example.flutterimagecompress.exif.Exif +import com.example.flutterimagecompress.format.FormatRegister +import com.example.flutterimagecompress.logger.log +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import java.io.ByteArrayOutputStream + +class CompressListHandler(private val call: MethodCall, result: MethodChannel.Result) : ResultHandler(result) { + + fun handle(context: Context) { + threadPool.execute { + @Suppress("UNCHECKED_CAST") val args: List = call.arguments as List + val arr = args[0] as ByteArray + var minWidth = args[1] as Int + var minHeight = args[2] as Int + val quality = args[3] as Int + val rotate = args[4] as Int + val autoCorrectionAngle = args[5] as Boolean + val format = args[6] as Int + val keepExif = args[7] as Boolean + val inSampleSize = args[8] as Int + + val exifRotate = if (autoCorrectionAngle) Exif.getRotationDegrees(arr) else 0 + + if (exifRotate == 270 || exifRotate == 90) { + val tmp = minWidth + minWidth = minHeight + minHeight = tmp + } + + val formatHandler = FormatRegister.findFormat(format) + + if (formatHandler == null) { + log("No support format.") + reply(null) + return@execute + } + + val targetRotate = rotate + exifRotate + + val outputStream = ByteArrayOutputStream() + try { + formatHandler.handleByteArray(context, arr, outputStream, minWidth, minHeight, quality, targetRotate, keepExif, inSampleSize) + reply(outputStream.toByteArray()) + } catch (e: CompressError) { + log(e.message) + if (FlutterImageCompressPlugin.showLog) e.printStackTrace() + reply(null) + } catch (e: Exception) { + if (FlutterImageCompressPlugin.showLog) e.printStackTrace() + reply(null) + } finally { + outputStream.close() + } + + } + } + + +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/ResultHandler.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/ResultHandler.kt new file mode 100644 index 000000000..7ad78af88 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/core/ResultHandler.kt @@ -0,0 +1,45 @@ +package com.example.flutterimagecompress.core + +import android.os.Handler +import android.os.Looper +import io.flutter.plugin.common.MethodChannel +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors + +abstract class ResultHandler(private var result: MethodChannel.Result?) { + + companion object { + @JvmStatic + private val handler = Handler(Looper.getMainLooper()) + + @JvmStatic + val threadPool: ExecutorService = Executors.newFixedThreadPool(8) + } + + private var isReply = false + + fun reply(any: Any?) { + if (isReply) { + return + } + isReply = true + val result = this.result + this.result = null + handler.post { + result?.success(any) + } + } + + fun replyError(code: String, message: String? = null, obj: Any? = null) { + if (isReply) { + return + } + isReply = true + val result = this.result + this.result = null + handler.post { + result?.error(code, message, obj) + } + } + +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exception/CompressError.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exception/CompressError.kt new file mode 100644 index 000000000..21b45815f --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exception/CompressError.kt @@ -0,0 +1,5 @@ +package com.example.flutterimagecompress.exception + +import java.lang.Exception + +class CompressError(message: String) : Exception(message) \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exif/Exif.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exif/Exif.kt new file mode 100644 index 000000000..88086cf20 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exif/Exif.kt @@ -0,0 +1,30 @@ +package com.example.flutterimagecompress.exif + +import androidx.exifinterface.media.ExifInterface +import java.io.ByteArrayInputStream +import java.io.File + + +object Exif { + fun getRotationDegrees(_bytes: ByteArray): Int { + return try { + getFromExifInterface(_bytes) + } catch (e: Exception) { + 0 + } + } + + private fun getFromExifInterface(byteArray: ByteArray): Int { + val exifInterface = ExifInterface(ByteArrayInputStream(byteArray)) + return exifInterface.rotationDegrees + } + + fun getRotationDegrees(file: File): Int { + return try { + ExifInterface(file.absolutePath).rotationDegrees + } catch (e: Exception) { + 0 + } + } + +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exif/ExifKeeper.java b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exif/ExifKeeper.java new file mode 100644 index 000000000..b795e930d --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/exif/ExifKeeper.java @@ -0,0 +1,131 @@ +package com.example.flutterimagecompress.exif; +/// create 2019-07-02 by cai + +import android.content.Context; +import android.util.Log; + +import org.apache.commons.io.IOUtils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import androidx.exifinterface.media.ExifInterface; + +public class ExifKeeper { + + private static List attributes = + Arrays.asList( + "FNumber", + "ExposureTime", + "ISOSpeedRatings", + "GPSAltitude", + "GPSAltitudeRef", + "FocalLength", + "GPSDateStamp", + "WhiteBalance", + "GPSProcessingMethod", + "GPSTimeStamp", + "DateTime", + "Flash", + "GPSLatitude", + "GPSLatitudeRef", + "GPSLongitude", + "GPSLongitudeRef", + "Make", + "Model"); + + private ExifInterface oldExif; + + public ExifKeeper(ExifInterface oldExif) { + this.oldExif = oldExif; + } + + public ExifKeeper(String filePath) throws IOException { + this.oldExif = new ExifInterface(filePath); + } + + public ExifKeeper(byte[] buf) throws IOException { + this.oldExif = new ExifInterface(new ByteArrayInputStream(buf)); + } + + private static void copyExif(ExifInterface oldExif, ExifInterface newExif) { + for (String attribute : attributes) { + setIfNotNull(oldExif, newExif, attribute); + } + try { + newExif.saveAttributes(); + } catch (IOException e) { + } + } + + private static void setIfNotNull(ExifInterface oldExif, ExifInterface newExif, String property) { + if (oldExif.getAttribute(property) != null) { + newExif.setAttribute(property, oldExif.getAttribute(property)); + } + } + + public ByteArrayOutputStream writeToOutputStream(Context context, ByteArrayOutputStream outputStream) { + FileOutputStream fileOutputStream = null; + FileInputStream fileInputStream = null; + try { + String uuid = UUID.randomUUID().toString(); + File file = new File(context.getCacheDir(), uuid + ".jpg"); + fileOutputStream = new FileOutputStream(file); + IOUtils.write(outputStream.toByteArray(), fileOutputStream); + fileOutputStream.close(); + + ExifInterface newExif = new ExifInterface(file.getAbsolutePath()); + + copyExif(oldExif, newExif); + + newExif.saveAttributes(); + fileOutputStream.close(); + + ByteArrayOutputStream newStream = new ByteArrayOutputStream(); + fileInputStream = new FileInputStream(file); + + IOUtils.copy(fileInputStream, newStream); + fileInputStream.close(); + return newStream; + + } catch (Exception ex) { + Log.e("ExifDataCopier", "Error preserving Exif data on selected image: " + ex); + } + + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if (fileOutputStream != null) { + try { + fileOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + return outputStream; + } + + public void copyExifToFile(File file) { + try { + ExifInterface newExif = new ExifInterface(file.getAbsolutePath()); + copyExif(oldExif, newExif); + newExif.saveAttributes(); + } catch (IOException e) { + return; + } + + } +} diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/ext/BitmapCompressExt.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/ext/BitmapCompressExt.kt new file mode 100644 index 000000000..7737c2c8d --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/ext/BitmapCompressExt.kt @@ -0,0 +1,71 @@ +package com.example.flutterimagecompress.ext + +import android.graphics.Bitmap +import android.graphics.Matrix +import com.example.flutterimagecompress.FlutterImageCompressPlugin +import java.io.ByteArrayOutputStream +import java.io.OutputStream +import kotlin.math.max +import kotlin.math.min + +fun Bitmap.compress(minWidth: Int, minHeight: Int, quality: Int, rotate: Int = 0, format: Int): ByteArray { + val outputStream = ByteArrayOutputStream() + compress(minWidth, minHeight, quality, rotate, outputStream, format) + return outputStream.toByteArray() +} + +fun Bitmap.compress(minWidth: Int, minHeight: Int, quality: Int, rotate: Int = 0, outputStream: OutputStream, format: Int = 0) { + val w = this.width.toFloat() + val h = this.height.toFloat() + + log("src width = $w") + log("src height = $h") + + val scale = calcScale(minWidth, minHeight) + + log("scale = $scale") + + val destW = w / scale + val destH = h / scale + + log("dst width = $destW") + log("dst height = $destH") + + Bitmap.createScaledBitmap(this, destW.toInt(), destH.toInt(), true) + .rotate(rotate) + .compress(convertFormatIndexToFormat(format), quality, outputStream) +} + +private fun log(any: Any?) { + if (FlutterImageCompressPlugin.showLog) { + println(any ?: "null") + } +} + +fun Bitmap.rotate(rotate: Int): Bitmap { + return if (rotate % 360 != 0) { + val matrix = Matrix() + matrix.setRotate(rotate.toFloat()) + // 围绕原地进行旋转 + Bitmap.createBitmap(this, 0, 0, width, height, matrix, false) + } else { + this + } +} + +fun Bitmap.calcScale(minWidth: Int, minHeight: Int): Float { + val w = width.toFloat() + val h = height.toFloat() + + val scaleW = w / minWidth.toFloat() + val scaleH = h / minHeight.toFloat() + + log("width scale = $scaleW") + log("height scale = $scaleH") + + return max(1f, min(scaleW, scaleH)) +} + +fun convertFormatIndexToFormat(type: Int): Bitmap.CompressFormat { + return if (type == 1) Bitmap.CompressFormat.PNG else if (type == 3) Bitmap.CompressFormat.WEBP else Bitmap.CompressFormat.JPEG +} diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/format/FormatRegister.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/format/FormatRegister.kt new file mode 100644 index 000000000..f6b77e521 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/format/FormatRegister.kt @@ -0,0 +1,19 @@ +package com.example.flutterimagecompress.format + +import android.util.SparseArray +import com.example.flutterimagecompress.handle.FormatHandler + +object FormatRegister { + + private val formatMap = SparseArray() + + fun registerFormat(handler: FormatHandler) { + formatMap.append(handler.type, handler) + } + + fun findFormat(formatIndex: Int): FormatHandler? { + return formatMap.get(formatIndex) + } + + +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/FormatHandler.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/FormatHandler.kt new file mode 100644 index 000000000..14b298178 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/FormatHandler.kt @@ -0,0 +1,15 @@ +package com.example.flutterimagecompress.handle + +import android.content.Context +import java.io.OutputStream + +interface FormatHandler { + + val type: Int + + val typeName: String + + fun handleByteArray(context: Context, byteArray: ByteArray, outputStream: OutputStream, minWidth: Int, minHeight: Int, quality: Int, rotate: Int, keepExif: Boolean, inSampleSize: Int) + + fun handleFile(context: Context, path: String, outputStream: OutputStream, minWidth: Int, minHeight: Int, quality: Int, rotate: Int, keepExif: Boolean, inSampleSize: Int) +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/common/CommonHandler.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/common/CommonHandler.kt new file mode 100644 index 000000000..c6054e7c4 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/common/CommonHandler.kt @@ -0,0 +1,114 @@ +package com.example.flutterimagecompress.handle.common + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import com.example.flutterimagecompress.exif.ExifKeeper +import com.example.flutterimagecompress.ext.calcScale +import com.example.flutterimagecompress.ext.compress +import com.example.flutterimagecompress.ext.rotate +import com.example.flutterimagecompress.handle.FormatHandler +import com.example.flutterimagecompress.logger.log +import java.io.ByteArrayOutputStream +import java.io.OutputStream + +class CommonHandler(override val type: Int) : FormatHandler { + + override val typeName: String + get() { + return when (type) { + 1 -> "png" + 3 -> "webp" + else -> "jpeg" + } + } + + private val bitmapFormat: Bitmap.CompressFormat + get() { + return when (type) { + 1 -> Bitmap.CompressFormat.PNG + 3 -> Bitmap.CompressFormat.WEBP + else -> Bitmap.CompressFormat.JPEG + } + } + + override fun handleByteArray(context: Context, byteArray: ByteArray, outputStream: OutputStream, minWidth: Int, minHeight: Int, quality: Int, rotate: Int, keepExif: Boolean, inSampleSize: Int) { + val result = compress(byteArray, minWidth, minHeight, quality, rotate, inSampleSize) + + if (keepExif && bitmapFormat == Bitmap.CompressFormat.JPEG) { + val byteArrayOutputStream = ByteArrayOutputStream() + byteArrayOutputStream.write(result) + val resultStream = ExifKeeper(byteArray).writeToOutputStream( + context, + byteArrayOutputStream + ) + outputStream.write(resultStream.toByteArray()) + } else { + outputStream.write(result) + } + + } + + private fun compress(arr: ByteArray, minWidth: Int, minHeight: Int, quality: Int, rotate: Int = 0, inSampleSize: Int): ByteArray { + val options = BitmapFactory.Options() + options.inJustDecodeBounds = false + options.inPreferredConfig = Bitmap.Config.RGB_565 + options.inSampleSize = inSampleSize + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { + @Suppress("DEPRECATION") + options.inDither = true + } + + val bitmap = BitmapFactory.decodeByteArray(arr, 0, arr.count(), options) + val outputStream = ByteArrayOutputStream() + + val w = bitmap.width.toFloat() + val h = bitmap.height.toFloat() + + log("src width = $w") + log("src height = $h") + + val scale = bitmap.calcScale(minWidth, minHeight) + + log("scale = $scale") + + val destW = w / scale + val destH = h / scale + + log("dst width = $destW") + log("dst height = $destH") + + Bitmap.createScaledBitmap(bitmap, destW.toInt(), destH.toInt(), true) + .rotate(rotate) + .compress(bitmapFormat, quality, outputStream) + + return outputStream.toByteArray() + } + + + override fun handleFile(context: Context, path: String, outputStream: OutputStream, minWidth: Int, minHeight: Int, quality: Int, rotate: Int, keepExif: Boolean, inSampleSize: Int) { + val options = BitmapFactory.Options() + options.inJustDecodeBounds = false + options.inPreferredConfig = Bitmap.Config.RGB_565 + options.inSampleSize = inSampleSize + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { + @Suppress("DEPRECATION") + options.inDither = true + } + val bitmap = BitmapFactory.decodeFile(path, options) + + val array = bitmap.compress(minWidth, minHeight, quality, rotate, type) + + if (keepExif && bitmapFormat == Bitmap.CompressFormat.JPEG) { + val byteArrayOutputStream = ByteArrayOutputStream() + byteArrayOutputStream.write(array) + val tmpOutputStream = ExifKeeper(path).writeToOutputStream( + context, + byteArrayOutputStream + ) + outputStream.write(tmpOutputStream.toByteArray()) + } else { + outputStream.write(array) + } + } +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/heif/HeifHandler.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/heif/HeifHandler.kt new file mode 100644 index 000000000..f4483c463 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/handle/heif/HeifHandler.kt @@ -0,0 +1,90 @@ +package com.example.flutterimagecompress.handle.heif + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.os.Build +import androidx.heifwriter.HeifWriter +import com.example.flutterimagecompress.ext.calcScale +import com.example.flutterimagecompress.ext.rotate +import com.example.flutterimagecompress.handle.FormatHandler +import com.example.flutterimagecompress.logger.log +import com.example.flutterimagecompress.util.TmpFileUtil +import java.io.OutputStream + +class HeifHandler : FormatHandler { + + override val type: Int + get() = 2 + + override val typeName: String + get() = "heif" + + override fun handleByteArray(context: Context, byteArray: ByteArray, outputStream: OutputStream, minWidth: Int, minHeight: Int, quality: Int, rotate: Int, keepExif: Boolean, inSampleSize: Int) { + val tmpFile = TmpFileUtil.createTmpFile(context) + compress(byteArray, minWidth, minHeight, quality, rotate, inSampleSize, tmpFile.absolutePath) + outputStream.write(tmpFile.readBytes()) + } + + private fun compress(arr: ByteArray, minWidth: Int, minHeight: Int, quality: Int, rotate: Int = 0, inSampleSize: Int, targetPath: String) { + val options = makeOption(inSampleSize) + val bitmap = BitmapFactory.decodeByteArray(arr, 0, arr.count(), options) + convertToHeif(bitmap, minWidth, minHeight, rotate, targetPath, quality) + } + + private fun compress(path: String, minWidth: Int, minHeight: Int, quality: Int, rotate: Int = 0, inSampleSize: Int, targetPath: String) { + val options = makeOption(inSampleSize) + val bitmap = BitmapFactory.decodeFile(path, options) + convertToHeif(bitmap, minWidth, minHeight, rotate, targetPath, quality) + } + + private fun makeOption(inSampleSize: Int): BitmapFactory.Options { + val options = BitmapFactory.Options() + options.inJustDecodeBounds = false + options.inPreferredConfig = Bitmap.Config.RGB_565 + options.inSampleSize = inSampleSize + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + @Suppress("DEPRECATION") + options.inDither = true + } + return options + } + + private fun convertToHeif(bitmap: Bitmap, minWidth: Int, minHeight: Int, rotate: Int, targetPath: String, quality: Int) { + val w = bitmap.width.toFloat() + val h = bitmap.height.toFloat() + + log("src width = $w") + log("src height = $h") + + val scale = bitmap.calcScale(minWidth, minHeight) + + log("scale = $scale") + + val destW = w / scale + val destH = h / scale + + log("dst width = $destW") + log("dst height = $destH") + + val result = Bitmap.createScaledBitmap(bitmap, destW.toInt(), destH.toInt(), true) + .rotate(rotate) + + val heifWriter = HeifWriter.Builder(targetPath, result.width, result.height, HeifWriter.INPUT_MODE_BITMAP) + .setQuality(quality) + .setMaxImages(1) + .build() + + heifWriter.start() + heifWriter.addBitmap(result) + heifWriter.stop(5000) + + heifWriter.close() + } + + override fun handleFile(context: Context, path: String, outputStream: OutputStream, minWidth: Int, minHeight: Int, quality: Int, rotate: Int, keepExif: Boolean, inSampleSize: Int) { + val tmpFile = TmpFileUtil.createTmpFile(context) + compress(path, minWidth, minHeight, quality, rotate, inSampleSize, tmpFile.absolutePath) + outputStream.write(tmpFile.readBytes()) + } +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/logger/LogExt.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/logger/LogExt.kt new file mode 100644 index 000000000..442185766 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/logger/LogExt.kt @@ -0,0 +1,10 @@ +package com.example.flutterimagecompress.logger + +import android.util.Log +import com.example.flutterimagecompress.FlutterImageCompressPlugin + +fun Any.log(any: Any?) { + if (FlutterImageCompressPlugin.showLog) { + Log.i("flutter_image_compress", any?.toString() ?: "null") + } +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/util/TmpFileUtil.kt b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/util/TmpFileUtil.kt new file mode 100644 index 000000000..c425ee511 --- /dev/null +++ b/thirdparty/flutter_image_compress/android/src/main/kotlin/com/example/flutterimagecompress/util/TmpFileUtil.kt @@ -0,0 +1,14 @@ +package com.example.flutterimagecompress.util + +import android.content.Context +import java.io.File +import java.util.* + +object TmpFileUtil { + + fun createTmpFile(context: Context): File { + val string = UUID.randomUUID().toString() + return File(context.cacheDir, string) + } + +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/.gitignore b/thirdparty/flutter_image_compress/example/.gitignore new file mode 100644 index 000000000..7731e7ea7 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/.gitignore @@ -0,0 +1,15 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ + +.flutter-plugins +.idea + + +.settings +.classpath +.project \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/.metadata b/thirdparty/flutter_image_compress/example/.metadata new file mode 100644 index 000000000..3037b487e --- /dev/null +++ b/thirdparty/flutter_image_compress/example/.metadata @@ -0,0 +1,8 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 3b309bda072a6b326e8aa4591a5836af600923ce + channel: dev diff --git a/thirdparty/flutter_image_compress/example/README.md b/thirdparty/flutter_image_compress/example/README.md new file mode 100644 index 000000000..d7a15c65f --- /dev/null +++ b/thirdparty/flutter_image_compress/example/README.md @@ -0,0 +1,8 @@ +# flutter_image_compress_example + +Demonstrates how to use the flutter_image_compress plugin. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.io/). diff --git a/thirdparty/flutter_image_compress/example/android/.gitignore b/thirdparty/flutter_image_compress/example/android/.gitignore new file mode 100644 index 000000000..65b7315af --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/.gitignore @@ -0,0 +1,10 @@ +*.iml +*.class +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +GeneratedPluginRegistrant.java diff --git a/thirdparty/flutter_image_compress/example/android/app/build.gradle b/thirdparty/flutter_image_compress/example/android/app/build.gradle new file mode 100644 index 000000000..047e215e5 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/build.gradle @@ -0,0 +1,67 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 29 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "com.example.flutterimagecompressexample" + minSdkVersion 16 + targetSdkVersion 29 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { +// print("app kotlin version is $kotlin_version") + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +// testImplementation 'junit:junit:4.12' +// androidTestImplementation 'androidx.test:runner:1.1.0-alpha4' +// androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4' +} diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/AndroidManifest.xml b/thirdparty/flutter_image_compress/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..07f9b379c --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/BuildConfig.java b/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/BuildConfig.java new file mode 100644 index 000000000..45b7e4ad1 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/BuildConfig.java @@ -0,0 +1,8 @@ +/*___Generated_by_IDEA___*/ + +package com.example.flutterimagecompressexample; + +/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ +public final class BuildConfig { + public final static boolean DEBUG = Boolean.parseBoolean(null); +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/Manifest.java b/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/Manifest.java new file mode 100644 index 000000000..3630dcdf4 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/Manifest.java @@ -0,0 +1,7 @@ +/*___Generated_by_IDEA___*/ + +package com.example.flutterimagecompressexample; + +/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ +public final class Manifest { +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/R.java b/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/R.java new file mode 100644 index 000000000..5ca0abe07 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/src/main/gen/com/example/flutterimagecompressexample/R.java @@ -0,0 +1,7 @@ +/*___Generated_by_IDEA___*/ + +package com.example.flutterimagecompressexample; + +/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ +public final class R { +} \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/kotlin/com/example/flutterimagecompressexample/MainActivity.kt b/thirdparty/flutter_image_compress/example/android/app/src/main/kotlin/com/example/flutterimagecompressexample/MainActivity.kt new file mode 100644 index 000000000..7a612e15c --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/src/main/kotlin/com/example/flutterimagecompressexample/MainActivity.kt @@ -0,0 +1,13 @@ +package com.example.flutterimagecompressexample + +import android.os.Bundle + +import io.flutter.app.FlutterActivity +import io.flutter.plugins.GeneratedPluginRegistrant + +class MainActivity(): FlutterActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + GeneratedPluginRegistrant.registerWith(this) + } +} diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/res/drawable/launch_background.xml b/thirdparty/flutter_image_compress/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000..304732f88 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..db77bb4b7 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..17987b79b Binary files /dev/null and b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..09d439148 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..d5f1c8d34 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..4d6372eeb Binary files /dev/null and b/thirdparty/flutter_image_compress/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/thirdparty/flutter_image_compress/example/android/app/src/main/res/values/styles.xml b/thirdparty/flutter_image_compress/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..00fa4417c --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/thirdparty/flutter_image_compress/example/android/build.gradle b/thirdparty/flutter_image_compress/example/android/build.gradle new file mode 100644 index 000000000..04a1deb50 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/build.gradle @@ -0,0 +1,66 @@ +import groovy.json.JsonSlurper + +buildscript { + ext.kotlin_version = '1.3.72' + def isChina = false + try { + def connection = new URL('https://api.ip.sb/geoip').openConnection() + connection.setRequestMethod('GET') + def reader = new BufferedReader(new InputStreamReader(connection.inputStream)) + def text = reader.readLine() + + def slurper = new JsonSlurper() + def states = slurper.parseText(text) + def country = states['country'] + isChina = country == 'China' + } catch (e) { + println(e) + } + + ext.isChina = isChina + + repositories { + if (isChina) { + maven { url 'https://maven.aliyun.com/repository/google' } + maven { url 'https://maven.aliyun.com/repository/jcenter' } + maven { + url 'https://storage.flutter-io.cn/download.flutter.io' + } + } else { + google() + jcenter() + } + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + + +allprojects { + repositories { + if (isChina) { + maven { url 'https://maven.aliyun.com/repository/google' } + maven { url 'https://maven.aliyun.com/repository/jcenter' } + maven { + url 'https://storage.flutter-io.cn/download.flutter.io' + } + } else { + google() + jcenter() + } + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/thirdparty/flutter_image_compress/example/android/gradle.properties b/thirdparty/flutter_image_compress/example/android/gradle.properties new file mode 100644 index 000000000..9d952a543 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/gradle.properties @@ -0,0 +1,6 @@ +android.enableJetifier=true +android.useAndroidX=true +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true + +android.debug.obsoleteApi=true \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/android/gradle/wrapper/gradle-wrapper.jar b/thirdparty/flutter_image_compress/example/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..13372aef5 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/thirdparty/flutter_image_compress/example/android/gradle/wrapper/gradle-wrapper.properties b/thirdparty/flutter_image_compress/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..ac209ce6f --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Jan 26 21:42:54 EET 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip diff --git a/thirdparty/flutter_image_compress/example/android/gradlew b/thirdparty/flutter_image_compress/example/android/gradlew new file mode 100755 index 000000000..9d82f7891 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/thirdparty/flutter_image_compress/example/android/gradlew.bat b/thirdparty/flutter_image_compress/example/android/gradlew.bat new file mode 100644 index 000000000..8a0b282aa --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/thirdparty/flutter_image_compress/example/android/settings.gradle b/thirdparty/flutter_image_compress/example/android/settings.gradle new file mode 100644 index 000000000..5a2f14fb1 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/thirdparty/flutter_image_compress/example/go/.gitignore b/thirdparty/flutter_image_compress/example/go/.gitignore new file mode 100644 index 000000000..e507dc623 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/.gitignore @@ -0,0 +1,2 @@ +build +.last_goflutter_check diff --git a/thirdparty/flutter_image_compress/example/go/assets/icon.png b/thirdparty/flutter_image_compress/example/go/assets/icon.png new file mode 100644 index 000000000..f4dfc8dea Binary files /dev/null and b/thirdparty/flutter_image_compress/example/go/assets/icon.png differ diff --git a/thirdparty/flutter_image_compress/example/go/cmd/import-flutter_image_compress-plugin.go b/thirdparty/flutter_image_compress/example/go/cmd/import-flutter_image_compress-plugin.go new file mode 100644 index 000000000..776aab43a --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/cmd/import-flutter_image_compress-plugin.go @@ -0,0 +1,13 @@ +package main + +// DO NOT EDIT, this file is generated by hover at compile-time for the flutter_image_compress plugin. + +import ( + flutter "github.com/go-flutter-desktop/go-flutter" + flutter_image_compress "github.com/openflutter/flutter_image_compress/go" +) + +func init() { + // Only the init function can be tweaked by plugin maker. + options = append(options, flutter.AddPlugin(&flutter_image_compress.FlutterImageCompressPlugin{})) +} diff --git a/thirdparty/flutter_image_compress/example/go/cmd/import-path_provider-plugin.go b/thirdparty/flutter_image_compress/example/go/cmd/import-path_provider-plugin.go new file mode 100644 index 000000000..fac0d4033 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/cmd/import-path_provider-plugin.go @@ -0,0 +1,16 @@ +package main + +// DO NOT EDIT, this file is generated by hover at compile-time for the path_provider plugin. + +import ( + flutter "github.com/go-flutter-desktop/go-flutter" + path_provider "github.com/go-flutter-desktop/plugins/path_provider" +) + +func init() { + // Only the init function can be tweaked by plugin maker. + options = append(options, flutter.AddPlugin(&path_provider.PathProviderPlugin{ + VendorName: flutter.ProjectOrganizationName, + ApplicationName: flutter.ProjectName, + })) +} diff --git a/thirdparty/flutter_image_compress/example/go/cmd/main.go b/thirdparty/flutter_image_compress/example/go/cmd/main.go new file mode 100644 index 000000000..10e3b09dc --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/cmd/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "image" + _ "image/png" + "os" + "path/filepath" + "strings" + + "github.com/go-flutter-desktop/go-flutter" + "github.com/pkg/errors" +) + +// vmArguments may be set by hover at compile-time +var vmArguments string + +func main() { + // DO NOT EDIT, add options in options.go + mainOptions := []flutter.Option{ + flutter.OptionVMArguments(strings.Split(vmArguments, ";")), + flutter.WindowIcon(iconProvider), + } + err := flutter.Run(append(options, mainOptions...)...) + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func iconProvider() ([]image.Image, error) { + execPath, err := os.Executable() + if err != nil { + return nil, errors.Wrap(err, "failed to resolve executable path") + } + execPath, err = filepath.EvalSymlinks(execPath) + if err != nil { + return nil, errors.Wrap(err, "failed to eval symlinks for executable path") + } + imgFile, err := os.Open(filepath.Join(filepath.Dir(execPath), "assets", "icon.png")) + if err != nil { + return nil, errors.Wrap(err, "failed to open assets/icon.png") + } + img, _, err := image.Decode(imgFile) + if err != nil { + return nil, errors.Wrap(err, "failed to decode image") + } + return []image.Image{img}, nil +} diff --git a/thirdparty/flutter_image_compress/example/go/cmd/options.go b/thirdparty/flutter_image_compress/example/go/cmd/options.go new file mode 100644 index 000000000..dc908387d --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/cmd/options.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/go-flutter-desktop/go-flutter" +) + +var options = []flutter.Option{ + flutter.WindowInitialDimensions(800, 1280), +} diff --git a/thirdparty/flutter_image_compress/example/go/go.mod b/thirdparty/flutter_image_compress/example/go/go.mod new file mode 100644 index 000000000..d0c5b13c3 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/go.mod @@ -0,0 +1,16 @@ +module flutter_image_compress_example/go + +go 1.13 + +require ( + github.com/chai2010/webp v1.1.0 // indirect + github.com/disintegration/imaging v1.6.2 // indirect + github.com/go-flutter-desktop/go-flutter v0.40.1 + github.com/go-flutter-desktop/plugins/path_provider v0.4.0 + github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect + github.com/openflutter/flutter_image_compress/go v0.0.0-00010101000000-000000000000 + github.com/pkg/errors v0.9.1 + golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect +) + +replace github.com/openflutter/flutter_image_compress/go => /Users/caijinglong/Documents/GitHub/flutter_image_compress/go diff --git a/thirdparty/flutter_image_compress/example/go/go.sum b/thirdparty/flutter_image_compress/example/go/go.sum new file mode 100644 index 000000000..75a12c71b --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/go.sum @@ -0,0 +1,58 @@ +github.com/Xuanwo/go-locale v0.2.0 h1:1N8SGG2VNpLl6VVa8ueZm3Nm+dxvk8ffY9aviKHl4IE= +github.com/Xuanwo/go-locale v0.2.0/go.mod h1:6qbT9M726OJgyiGZro2YwPmx63wQzlH+VvtjJWQoftw= +github.com/adrg/xdg v0.2.1 h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic= +github.com/adrg/xdg v0.2.1/go.mod h1:ZuOshBmzV4Ta+s23hdfFZnBsdzmoR3US0d7ErpqSbTQ= +github.com/chai2010/webp v1.1.0 h1:4Ei0/BRroMF9FaXDG2e4OxwFcuW2vcXd+A6tyqTJUQQ= +github.com/chai2010/webp v1.1.0/go.mod h1:LP12PG5IFmLGHUU26tBiCBKnghxx3toZFwDjOYvd3Ow= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= +github.com/go-flutter-desktop/go-flutter v0.37.0/go.mod h1:8tjt3yZ3lTNLqgzWeH90f1uhCR9BL68LFoiy/n0aw/w= +github.com/go-flutter-desktop/go-flutter v0.40.1 h1:4GC+9sc4jLxFoqLcHIGBNHdcF99ABC30g2q9iIQ+100= +github.com/go-flutter-desktop/go-flutter v0.40.1/go.mod h1:VNXgUO61Nxa9y/5jHQJFFuWVK9oNQF56MPKPUgQXwlU= +github.com/go-flutter-desktop/plugins v0.0.0-20200502124433-338c83f03c4f h1:fxuMAOcdCv/8KXQOF2De2Jkvrj8hshM4dnKU3VpRkKg= +github.com/go-flutter-desktop/plugins/path_provider v0.4.0 h1:LhYqOJjwuRjf9MzmbvkejCtLqrEEeBzrsCWkVONG6uw= +github.com/go-flutter-desktop/plugins/path_provider v0.4.0/go.mod h1:e0aUP0dqcGaw5EZpCYzlK7M/T6X0ueWYJXImrE25vb4= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200420212212-258d9bec320e h1:8ywu4ELC/6owgOZlZx75CyYS5AYwUT2L+hzPModKvag= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200420212212-258d9bec320e/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/thirdparty/flutter_image_compress/example/go/hover.yaml b/thirdparty/flutter_image_compress/example/go/hover.yaml new file mode 100644 index 000000000..c9b114bab --- /dev/null +++ b/thirdparty/flutter_image_compress/example/go/hover.yaml @@ -0,0 +1,10 @@ +#application-name: "flutter_image_compress_example" # Uncomment to modify this value. +#executable-name: "flutter_image_compress_example" # Uncomment to modify this value. Only lowercase a-z, numbers, underscores and no spaces +#package-name: "flutterimagecompressexample" # Uncomment to modify this value. Only lowercase a-z, numbers and no underscores or spaces +license: "" # MANDATORY: Fill in your SPDX license name: https://spdx.org/licenses +target: lib/main_desktop.dart +branch: "" # Change to "@latest" to download the latest go-flutter version on every build +# cache-path: "/home/YOURUSERNAME/.cache/" # https://github.com/go-flutter-desktop/go-flutter/issues/184 +# opengl: "none" # Uncomment this line if you have trouble with your OpenGL driver (https://github.com/go-flutter-desktop/go-flutter/issues/272) +docker: false +engine-version: "" # change to a engine version commit diff --git a/thirdparty/flutter_image_compress/example/img/auto-angle.jpg b/thirdparty/flutter_image_compress/example/img/auto-angle.jpg new file mode 100644 index 000000000..1450a45a3 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/img/auto-angle.jpg differ diff --git a/thirdparty/flutter_image_compress/example/img/have-exif.jpg b/thirdparty/flutter_image_compress/example/img/have-exif.jpg new file mode 100644 index 000000000..e4c982a77 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/img/have-exif.jpg differ diff --git a/thirdparty/flutter_image_compress/example/img/header.png b/thirdparty/flutter_image_compress/example/img/header.png new file mode 100644 index 000000000..a74024328 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/img/header.png differ diff --git a/thirdparty/flutter_image_compress/example/img/img.jpg b/thirdparty/flutter_image_compress/example/img/img.jpg new file mode 100644 index 000000000..ceed9bedb Binary files /dev/null and b/thirdparty/flutter_image_compress/example/img/img.jpg differ diff --git a/thirdparty/flutter_image_compress/example/img/transparent-background.png b/thirdparty/flutter_image_compress/example/img/transparent-background.png new file mode 100644 index 000000000..4b81a27f5 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/img/transparent-background.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/.gitignore b/thirdparty/flutter_image_compress/example/ios/.gitignore new file mode 100644 index 000000000..79cc4da80 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/.gitignore @@ -0,0 +1,45 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/app.flx +/Flutter/app.zip +/Flutter/flutter_assets/ +/Flutter/App.framework +/Flutter/Flutter.framework +/Flutter/Generated.xcconfig +/ServiceDefinitions.json + +Pods/ +.symlinks/ diff --git a/thirdparty/flutter_image_compress/example/ios/Flutter/AppFrameworkInfo.plist b/thirdparty/flutter_image_compress/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000..9367d483e --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/thirdparty/flutter_image_compress/example/ios/Flutter/Debug.xcconfig b/thirdparty/flutter_image_compress/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..e8efba114 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/thirdparty/flutter_image_compress/example/ios/Flutter/Flutter.podspec b/thirdparty/flutter_image_compress/example/ios/Flutter/Flutter.podspec new file mode 100644 index 000000000..5ca30416b --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Flutter/Flutter.podspec @@ -0,0 +1,18 @@ +# +# NOTE: This podspec is NOT to be published. It is only used as a local source! +# + +Pod::Spec.new do |s| + s.name = 'Flutter' + s.version = '1.0.0' + s.summary = 'High-performance, high-fidelity mobile apps.' + s.description = <<-DESC +Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS. + DESC + s.homepage = 'https://flutter.io' + s.license = { :type => 'MIT' } + s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } + s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } + s.ios.deployment_target = '8.0' + s.vendored_frameworks = 'Flutter.framework' +end diff --git a/thirdparty/flutter_image_compress/example/ios/Flutter/Release.xcconfig b/thirdparty/flutter_image_compress/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..399e9340e --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/thirdparty/flutter_image_compress/example/ios/Podfile b/thirdparty/flutter_image_compress/example/ios/Podfile new file mode 100644 index 000000000..794a4052f --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Podfile @@ -0,0 +1,89 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + generated_key_values = {} + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) do |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + generated_key_values[podname] = podpath + else + puts "Invalid plugin specification: #{line}" + end + end + generated_key_values +end + +target 'Runner' do + # Flutter Pod + + copied_flutter_dir = File.join(__dir__, 'Flutter') + copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') + copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') + unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) + # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. + # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. + # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + + generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') + unless File.exist?(generated_xcode_build_settings_path) + raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) + cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; + + unless File.exist?(copied_framework_path) + FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) + end + unless File.exist?(copied_podspec_path) + FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) + end + end + + # Keep pod path relative so it can be checked into Podfile.lock. + pod 'Flutter', :path => 'Flutter' + + # Plugin Pods + + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.each do |name, path| + # symlink = File.join('.symlinks', 'plugins', name) + # File.symlink(path, symlink) + # pod name, :path => File.join(symlink, 'ios') + specPath = "#{path}/ios/#{name}.podspec" + pod name,:path=>specPath + end +end + +# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. +install! 'cocoapods', :disable_input_output_paths => true + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/thirdparty/flutter_image_compress/example/ios/Podfile.lock b/thirdparty/flutter_image_compress/example/ios/Podfile.lock new file mode 100644 index 000000000..7326ed63c --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Podfile.lock @@ -0,0 +1,57 @@ +PODS: + - Flutter (1.0.0) + - flutter_image_compress (0.0.1): + - Flutter + - Mantle + - SDWebImageWebPCoder + - libwebp (1.1.0): + - libwebp/demux (= 1.1.0) + - libwebp/mux (= 1.1.0) + - libwebp/webp (= 1.1.0) + - libwebp/demux (1.1.0): + - libwebp/webp + - libwebp/mux (1.1.0): + - libwebp/demux + - libwebp/webp (1.1.0) + - Mantle (2.1.1): + - Mantle/extobjc (= 2.1.1) + - Mantle/extobjc (2.1.1) + - path_provider (0.0.1): + - Flutter + - SDWebImage/Core (5.6.1) + - SDWebImageWebPCoder (0.5.0): + - libwebp (~> 1.0) + - SDWebImage/Core (~> 5.5) + +DEPENDENCIES: + - Flutter (from `Flutter`) + - flutter_image_compress (from `/Volumes/Samsung-T5/code/flutter/plugins/flutter_image_compress/ios/flutter_image_compress.podspec`) + - path_provider (from `/Users/caijinglong/.pub-cache/hosted/pub.flutter-io.cn/path_provider-0.4.1/ios/path_provider.podspec`) + +SPEC REPOS: + trunk: + - libwebp + - Mantle + - SDWebImage + - SDWebImageWebPCoder + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + flutter_image_compress: + :path: "/Volumes/Samsung-T5/code/flutter/plugins/flutter_image_compress/ios/flutter_image_compress.podspec" + path_provider: + :path: "/Users/caijinglong/.pub-cache/hosted/pub.flutter-io.cn/path_provider-0.4.1/ios/path_provider.podspec" + +SPEC CHECKSUMS: + Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + flutter_image_compress: 082f8daaf6c1b0c9fe798251c750ef0ecd98d7ae + libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3 + Mantle: 35238ae6f2e2b2d474fa7b67fee82a59fea71915 + path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259 + SDWebImage: 7edb9c3ea661e77a66661f7f044de8c1b55d1120 + SDWebImageWebPCoder: e7ae855f058e3dcae99696920b6a5d134e9dcddf + +PODFILE CHECKSUM: 4d8d59437a9bee20e84f185bba22b518812142d3 + +COCOAPODS: 1.9.1 diff --git a/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/project.pbxproj b/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..8e2eb08e6 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,482 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 8FC1B0E5086B82A6FC845E0E /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E999912872996623C1AA6EA3 /* libPods-Runner.a */; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 104B390780BA384E19B9CD64 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 26D8CA1FA8483F82FD0C13FB /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E999912872996623C1AA6EA3 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8FC1B0E5086B82A6FC845E0E /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1F80C4BD5877066B2B68A73E /* Frameworks */ = { + isa = PBXGroup; + children = ( + E999912872996623C1AA6EA3 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 587FC836BA6286FCA8336FE7 /* Pods */ = { + isa = PBXGroup; + children = ( + 26D8CA1FA8483F82FD0C13FB /* Pods-Runner.debug.xcconfig */, + 104B390780BA384E19B9CD64 /* Pods-Runner.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 587FC836BA6286FCA8336FE7 /* Pods */, + 1F80C4BD5877066B2B68A73E /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + ABE12B2AE152827375ECA585 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + E3FBB171A63B8C37FA0A5739 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = S5GU4EMC47; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + }; + ABE12B2AE152827375ECA585 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + E3FBB171A63B8C37FA0A5739 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S5GU4EMC47; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = "top.kikt.flutter-image-compress-example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S5GU4EMC47; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = "top.kikt.flutter-image-compress-example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..1d526a16e --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000..5eddc4930 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/flutter_image_compress/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/thirdparty/flutter_image_compress/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..21a3cc14c --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/thirdparty/flutter_image_compress/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/thirdparty/flutter_image_compress/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/AppDelegate.h b/thirdparty/flutter_image_compress/example/ios/Runner/AppDelegate.h new file mode 100644 index 000000000..36e21bbf9 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/AppDelegate.m b/thirdparty/flutter_image_compress/example/ios/Runner/AppDelegate.m new file mode 100644 index 000000000..59a72e90b --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d36b1fab2 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 000000000..3d43d11e6 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 000000000..28c6bf030 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 000000000..f091b6b0b Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 000000000..4cde12118 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 000000000..d0ef06e7e Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 000000000..dcdc2306c Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 000000000..c8f9ed8f5 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 000000000..75b2d164a Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 000000000..c4df70d39 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 000000000..6a84f41e1 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 000000000..d0e1f5853 Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 000000000..0bedcf2fd --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000..89c2725b7 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/thirdparty/flutter_image_compress/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..f2e259c7c --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Base.lproj/Main.storyboard b/thirdparty/flutter_image_compress/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000..f3c28516f --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/Info.plist b/thirdparty/flutter_image_compress/example/ios/Runner/Info.plist new file mode 100644 index 000000000..c507a3eaf --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_image_compress_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/thirdparty/flutter_image_compress/example/ios/Runner/main.m b/thirdparty/flutter_image_compress/example/ios/Runner/main.m new file mode 100644 index 000000000..dff6597e4 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/thirdparty/flutter_image_compress/example/lib/const/resource.dart b/thirdparty/flutter_image_compress/example/lib/const/resource.dart new file mode 100644 index 000000000..6603c251b --- /dev/null +++ b/thirdparty/flutter_image_compress/example/lib/const/resource.dart @@ -0,0 +1,18 @@ +/// generate by resouce_generator library, shouldn't edit. +class R { + + /// ![preview](file:///Users/caijinglong/Documents/GitHub/flutter_image_compress/example/./img/auto-angle.jpg) + static const String IMG_AUTO_ANGLE_JPG = "img/auto-angle.jpg"; + + /// ![preview](file:///Users/caijinglong/Documents/GitHub/flutter_image_compress/example/./img/have-exif.jpg) + static const String IMG_HAVE_EXIF_JPG = "img/have-exif.jpg"; + + /// ![preview](file:///Users/caijinglong/Documents/GitHub/flutter_image_compress/example/./img/header.png) + static const String IMG_HEADER_PNG = "img/header.png"; + + /// ![preview](file:///Users/caijinglong/Documents/GitHub/flutter_image_compress/example/./img/img.jpg) + static const String IMG_IMG_JPG = "img/img.jpg"; + + /// ![preview](file:///Users/caijinglong/Documents/GitHub/flutter_image_compress/example/./img/transparent-background.png) + static const String IMG_TRANSPARENT_BACKGROUND_PNG = "img/transparent-background.png"; +} diff --git a/thirdparty/flutter_image_compress/example/lib/main.dart b/thirdparty/flutter_image_compress/example/lib/main.dart new file mode 100644 index 000000000..58c2ab354 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/lib/main.dart @@ -0,0 +1,391 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_image_compress/flutter_image_compress.dart'; +import 'package:path_provider/path_provider.dart' as path_provider; + +import 'const/resource.dart'; +import 'time_logger.dart'; +// import 'package:image_picker/image_picker.dart'; + +void main() { + runApp(new MyApp()); + FlutterImageCompress.showNativeLog = true; +} + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => new _MyAppState(); +} + +class _MyAppState extends State { + @override + void initState() { + super.initState(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future compress() async { + final img = AssetImage("img/img.jpg"); + print("pre compress"); + final config = new ImageConfiguration(); + + AssetBundleImageKey key = await img.obtainKey(config); + final ByteData data = await key.bundle.load(key.name); + + final beforeCompress = data.lengthInBytes; + print("beforeCompress = $beforeCompress"); + + final result = + await FlutterImageCompress.compressWithList(data.buffer.asUint8List()); + + print("after = ${result?.length ?? 0}"); + } + + ImageProvider provider; + + @override + Widget build(BuildContext context) { + return new MaterialApp( + home: new Scaffold( + appBar: new AppBar( + title: const Text('Plugin example app'), + ), + body: ListView( + children: [ + AspectRatio( + child: Image( + image: provider ?? AssetImage("img/img.jpg"), + width: double.infinity, + fit: BoxFit.contain, + ), + aspectRatio: 1 / 1, + ), + FlatButton( + child: Text('CompressFile and rotate 180'), + onPressed: _testCompressFile, + ), + FlatButton( + child: Text('CompressAndGetFile and rotate 90'), + onPressed: getFileImage, + ), + FlatButton( + child: Text('CompressAsset and rotate 135'), + onPressed: () => testCompressAsset("img/img.jpg"), + ), + FlatButton( + child: Text('CompressList and rotate 270'), + onPressed: compressListExample, + ), + FlatButton( + child: Text('test compress auto angle'), + onPressed: _compressAssetAndAutoRotate, + ), + FlatButton( + child: Text('Test png '), + onPressed: _compressPngImage, + ), + FlatButton( + child: Text('Format transparent PNG'), + onPressed: _compressTransPNG, + ), + FlatButton( + child: Text('Restore transparent PNG'), + onPressed: _restoreTransPNG, + ), + FlatButton( + child: Text('Keep exif image'), + onPressed: _compressImageAndKeepExif, + ), + FlatButton( + child: Text('Convert to heic format and print the file url'), + onPressed: _compressHeicExample, + ), + FlatButton( + child: Text('Convert to webp format, Just support android'), + onPressed: _compressAndroidWebpExample, + ), + ], + ), + floatingActionButton: FloatingActionButton( + child: Icon(Icons.computer), + onPressed: () => setState(() => this.provider = null), + tooltip: "show origin asset", + ), + ), + ); + } + + Future getTemporaryDirectory() async { + return Directory.systemTemp; + } + + void _testCompressFile() async { + final img = AssetImage("img/img.jpg"); + print("pre compress"); + final config = new ImageConfiguration(); + + AssetBundleImageKey key = await img.obtainKey(config); + final ByteData data = await key.bundle.load(key.name); + final dir = await path_provider.getTemporaryDirectory(); + print('dir = $dir'); + + File file = createFile("${dir.absolute.path}/test.png"); + file.writeAsBytesSync(data.buffer.asUint8List()); + + final result = await testCompressFile(file); + ImageProvider provider = MemoryImage(result); + this.provider = provider; + setState(() {}); + } + + File createFile(String path) { + final file = File(path); + if (!file.existsSync()) { + file.createSync(recursive: true); + } + + return file; + } + + Future getExampleFilePath() async { + final img = AssetImage("img/img.jpg"); + print("pre compress"); + final config = new ImageConfiguration(); + + AssetBundleImageKey key = await img.obtainKey(config); + final ByteData data = await key.bundle.load(key.name); + final dir = await path_provider.getTemporaryDirectory(); + + File file = createFile("${dir.absolute.path}/test.png"); + file.createSync(recursive: true); + file.writeAsBytesSync(data.buffer.asUint8List()); + return file.absolute.path; + } + + void getFileImage() async { + final img = AssetImage("img/img.jpg"); + print("pre compress"); + final config = new ImageConfiguration(); + + AssetBundleImageKey key = await img.obtainKey(config); + final ByteData data = await key.bundle.load(key.name); + final dir = await path_provider.getTemporaryDirectory(); + + File file = createFile("${dir.absolute.path}/test.png"); + file.writeAsBytesSync(data.buffer.asUint8List()); + + final targetPath = dir.absolute.path + "/temp.jpg"; + final imgFile = await testCompressAndGetFile(file, targetPath); + + provider = FileImage(imgFile); + setState(() {}); + } + + Future testCompressFile(File file) async { + print("testCompressFile"); + final result = await FlutterImageCompress.compressWithFile( + file.absolute.path, + minWidth: 2300, + minHeight: 1500, + quality: 94, + rotate: 180, + ); + print(file.lengthSync()); + print(result.length); + return result; + } + + Future testCompressAndGetFile(File file, String targetPath) async { + print("testCompressAndGetFile"); + final result = await FlutterImageCompress.compressAndGetFile( + file.absolute.path, + targetPath, + quality: 90, + minWidth: 1024, + minHeight: 1024, + rotate: 90, + ); + + print(file.lengthSync()); + print(result.lengthSync()); + + return result; + } + + Future testCompressAsset(String assetName) async { + print("testCompressAsset"); + final list = await FlutterImageCompress.compressAssetImage( + assetName, + minHeight: 1920, + minWidth: 1080, + quality: 96, + rotate: 135, + ); + + this.provider = MemoryImage(Uint8List.fromList(list)); + setState(() {}); + } + + Future compressListExample() async { + final data = await rootBundle.load("img/img.jpg"); + + final memory = await testComporessList(data.buffer.asUint8List()); + + setState(() { + this.provider = MemoryImage(memory); + }); + } + + Future testComporessList(Uint8List list) async { + final result = await FlutterImageCompress.compressWithList( + list, + minHeight: 1080, + minWidth: 1080, + quality: 96, + rotate: 270, + format: CompressFormat.webp, + ); + print(list.length); + print(result.length); + return result; + } + + void writeToFile(List list, String filePath) { + final file = File(filePath); + file.writeAsBytes(list, flush: true, mode: FileMode.write); + } + + void _compressAssetAndAutoRotate() async { + final result = await FlutterImageCompress.compressAssetImage( + R.IMG_AUTO_ANGLE_JPG, + minWidth: 1000, + quality: 95, + // autoCorrectionAngle: false, + ); + final u8list = Uint8List.fromList(result); + this.provider = MemoryImage(u8list); + setState(() {}); + } + + void _compressPngImage() async { + final result = await FlutterImageCompress.compressAssetImage( + R.IMG_HEADER_PNG, + minWidth: 300, + minHeight: 500, + ); + + final u8list = Uint8List.fromList(result); + this.provider = MemoryImage(u8list); + setState(() {}); + } + + void _compressTransPNG() async { + final bytes = + await getAssetImageUint8List(R.IMG_TRANSPARENT_BACKGROUND_PNG); + final result = await FlutterImageCompress.compressWithList( + bytes, + minHeight: 100, + minWidth: 100, + format: CompressFormat.png, + ); + + final u8list = Uint8List.fromList(result); + this.provider = MemoryImage(u8list); + setState(() {}); + } + + void _restoreTransPNG() async { + this.provider = AssetImage(R.IMG_TRANSPARENT_BACKGROUND_PNG); + setState(() {}); + } + + void _compressImageAndKeepExif() async { + final result = await FlutterImageCompress.compressAssetImage( + R.IMG_AUTO_ANGLE_JPG, + minWidth: 500, + minHeight: 600, + // autoCorrectionAngle: false, + keepExif: true, + ); + + this.provider = MemoryImage(Uint8List.fromList(result)); + setState(() {}); + + // final dir = (await path_provider.getTemporaryDirectory()).path; + // final f = File("$dir/tmp.jpg"); + // f.writeAsBytesSync(result); + // print("f.path = ${f.path}"); + } + + void _compressHeicExample() async { + print("start compress"); + final logger = TimeLogger(); + logger.startRecoder(); + final tmpDir = (await getTemporaryDirectory()).path; + final target = "$tmpDir/${DateTime.now().millisecondsSinceEpoch}.heic"; + final srcPath = await getExampleFilePath(); + final result = await FlutterImageCompress.compressAndGetFile( + srcPath, + target, + format: CompressFormat.heic, + quality: 90, + ); + print("Compress heic success."); + logger.logTime(); + print("src, path = $srcPath length = ${File(srcPath).lengthSync()}"); + print( + "Compress heic result path: ${result.absolute.path}, size: ${result.lengthSync()}"); + } + + void _compressAndroidWebpExample() async { + // Android compress very nice, but the iOS encode UIImage to webp is slow. + final logger = TimeLogger(); + logger.startRecoder(); + print("start compress webp"); + final quality = 90; + final tmpDir = (await getTemporaryDirectory()).path; + final target = + "$tmpDir/${DateTime.now().millisecondsSinceEpoch}-$quality.webp"; + final srcPath = await getExampleFilePath(); + final result = await FlutterImageCompress.compressAndGetFile( + srcPath, + target, + format: CompressFormat.webp, + minHeight: 800, + minWidth: 800, + quality: quality, + ); + print("Compress webp success."); + logger.logTime(); + print("src, path = $srcPath length = ${File(srcPath).lengthSync()}"); + print( + "Compress webp result path: ${result.absolute.path}, size: ${result.lengthSync()}"); + + provider = FileImage(result); + setState(() {}); + } +} + +Future getAssetImageUint8List(String key) async { + final byteData = await rootBundle.load(key); + return byteData.buffer.asUint8List(); +} + +double calcScale({ + double srcWidth, + double srcHeight, + double minWidth, + double minHeight, +}) { + final scaleW = srcWidth / minWidth; + final scaleH = srcHeight / minHeight; + + final scale = math.max(1.0, math.min(scaleW, scaleH)); + + return scale; +} diff --git a/thirdparty/flutter_image_compress/example/lib/main_desktop.dart b/thirdparty/flutter_image_compress/example/lib/main_desktop.dart new file mode 100644 index 000000000..c0d8d19d1 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/lib/main_desktop.dart @@ -0,0 +1,10 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_image_compress/flutter_image_compress.dart'; + +import 'main.dart' as m; + +main() { + debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; + FlutterImageCompress.validator.ignoreCheckSupportPlatform = true; + m.main(); +} diff --git a/thirdparty/flutter_image_compress/example/lib/time_logger.dart b/thirdparty/flutter_image_compress/example/lib/time_logger.dart new file mode 100644 index 000000000..491088763 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/lib/time_logger.dart @@ -0,0 +1,20 @@ +class TimeLogger { + String tag; + + TimeLogger([this.tag = ""]); + + int start; + + void startRecoder() { + start = DateTime.now().millisecondsSinceEpoch; + } + + void logTime() { + final diff = DateTime.now().millisecondsSinceEpoch - start; + if (tag != "") { + print("$tag : $diff ms"); + } else { + print("run time $diff ms"); + } + } +} diff --git a/thirdparty/flutter_image_compress/example/lib/try_catch_example.dart b/thirdparty/flutter_image_compress/example/lib/try_catch_example.dart new file mode 100644 index 000000000..9f91ee6c6 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/lib/try_catch_example.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:flutter_image_compress/flutter_image_compress.dart'; + +class TryCatchExample { + Future> compressAndTryCatch(String path) async { + List result; + try { + result = await FlutterImageCompress.compressWithFile(path, + format: CompressFormat.heic); + } on UnsupportedError catch (e) { + print(e.message); + result = await FlutterImageCompress.compressWithFile(path, + format: CompressFormat.jpeg); + } on Error catch (e) { + print(e.toString()); + print(e.stackTrace); + } on Exception catch (e) { + print(e.toString()); + } + return result; + } +} diff --git a/thirdparty/flutter_image_compress/example/pubspec.yaml b/thirdparty/flutter_image_compress/example/pubspec.yaml new file mode 100644 index 000000000..84465c1c0 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/pubspec.yaml @@ -0,0 +1,74 @@ +name: flutter_image_compress_example +description: Demonstrates how to use the flutter_image_compress plugin. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# Read more about versioning at semver.org. +version: 1.0.0+1 + +environment: + sdk: ">=2.0.0-dev.68.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + + flutter_image_compress: + path: ../ + + path_provider: ^0.4.1 + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - img/ + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/thirdparty/flutter_image_compress/example/run_hover.sh b/thirdparty/flutter_image_compress/example/run_hover.sh new file mode 100644 index 000000000..32f8c1b04 --- /dev/null +++ b/thirdparty/flutter_image_compress/example/run_hover.sh @@ -0,0 +1,2 @@ +rm -rf go/build +hover run \ No newline at end of file diff --git a/thirdparty/flutter_image_compress/example/test/widget_test.dart b/thirdparty/flutter_image_compress/example/test/widget_test.dart new file mode 100644 index 000000000..3737ee52c --- /dev/null +++ b/thirdparty/flutter_image_compress/example/test/widget_test.dart @@ -0,0 +1,25 @@ +// // This is a basic Flutter widget test. +// // To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter +// // provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to +// // find child widgets in the widget tree, read text, and verify that the values of widget properties +// // are correct. + +// import 'package:flutter/material.dart'; +// import 'package:flutter_test/flutter_test.dart'; + +// import 'package:flutter_image_compress_example/main.dart'; + +// void main() { +// testWidgets('Verify Platform version', (WidgetTester tester) async { +// // Build our app and trigger a frame. +// await tester.pumpWidget(new MyApp()); + +// // Verify that platform version is retrieved. +// expect( +// find.byWidgetPredicate( +// (Widget widget) => +// widget is Text && widget.data.startsWith('Running on:'), +// ), +// findsOneWidget); +// }); +// } diff --git a/thirdparty/flutter_image_compress/go/README.md b/thirdparty/flutter_image_compress/go/README.md new file mode 100644 index 000000000..31ba19179 --- /dev/null +++ b/thirdparty/flutter_image_compress/go/README.md @@ -0,0 +1,34 @@ +# flutter_image_compress + +This Go package implements the host-side of the Flutter [flutter_image_compress](https://github.com/openflutter/flutter_image_compress) plugin. + +## Usage + +Import as: + +```go +import flutter_image_compress "github.com/openflutter/flutter_image_compress/go" +``` + +Then add the following option to your go-flutter [application options](https://github.com/go-flutter-desktop/go-flutter/wiki/Plugin-info): + +```go +flutter.AddPlugin(&flutter_image_compress.FlutterImageCompressPlugin{}), +``` + +## Support + +- [x] fileToFile +- [x] listToList +- [x] listToFile + +- [x] minWidth +- [x] minHeight +- [x] rotate +- [x] quality + +- [x] jpeg +- [x] png + +- [ ] keepExif +- [ ] autoCorrectionAngle diff --git a/thirdparty/flutter_image_compress/go/compress.go b/thirdparty/flutter_image_compress/go/compress.go new file mode 100644 index 000000000..37de79e91 --- /dev/null +++ b/thirdparty/flutter_image_compress/go/compress.go @@ -0,0 +1,63 @@ +package flutter_image_compress + +import ( + "image" + "image/color" + _ "image/gif" + _ "image/jpeg" + _ "image/png" + "io" + "os" + + "github.com/disintegration/imaging" + "github.com/nfnt/resize" + _ "golang.org/x/image/webp" +) + +// Rotate image +func RotateImage(img image.Image, degree int) image.Image { + return imaging.Rotate(img, float64(degree), color.Transparent) +} + +// Scale image +func ScaleImage(reader io.Reader, minWidth, minHeight int32) (img image.Image, err error) { + img, _, err = image.Decode(reader) + if err != nil { + return + } + + w, h := calcTargetSize(img, minHeight, minHeight) + + img = resize.Resize(w, h, img, resize.Lanczos3) + return +} + +func calcTargetSize(img image.Image, minWidth, minHeight int32) (uint, uint) { + srcW := float32(img.Bounds().Size().X) + srcH := float32(img.Bounds().Size().Y) + + scaleW := srcW / float32(minWidth) + scaleH := srcH / float32(minHeight) + + scale := scaleW + if scaleH < scaleW { + scale = scaleH + } + + if scale < 1 { + scale = 1 + } + + return uint(srcW / scale), uint(srcH / scale) +} + +func pathExists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} diff --git a/thirdparty/flutter_image_compress/go/dlib/README.md b/thirdparty/flutter_image_compress/go/dlib/README.md new file mode 100644 index 000000000..f2da2547b --- /dev/null +++ b/thirdparty/flutter_image_compress/go/dlib/README.md @@ -0,0 +1,14 @@ +The `dlib` folder is used for the plugins which use `cgo`. + +If your go-flutter plugin dose't use `cgo`, just ignore this file and the `dlib` folder. + +When you need to link prebuild dynamic libraries and frameworks, +you should copy the prebuild dynamic libraries and frameworks to `dlib`/${os} folder. + +`hover plugins get` copy this files to path `./go/build/intermediates` of go-flutter app project. +`hover run` copy files from `./go/build/intermediates/${targetOS}` to `./go/build/outputs/${targetOS}`. +And `-L{./go/build/outputs/${targetOS}}` is appended to `cgoLdflags` automatically. +Also `-F{./go/build/outputs/${targetOS}}` is appended to `cgoLdflags` on Mac OS + +Attention: `hover` can't resolve the conflicts +if two different go-flutter plugins have file with the same name in there dlib folder diff --git a/thirdparty/flutter_image_compress/go/go.mod b/thirdparty/flutter_image_compress/go/go.mod new file mode 100644 index 000000000..6f6f08ab8 --- /dev/null +++ b/thirdparty/flutter_image_compress/go/go.mod @@ -0,0 +1,5 @@ +module github.com/openflutter/flutter_image_compress/go + +go 1.13 + +require github.com/go-flutter-desktop/go-flutter v0.40.1 diff --git a/thirdparty/flutter_image_compress/go/go.sum b/thirdparty/flutter_image_compress/go/go.sum new file mode 100644 index 000000000..7e7130ec7 --- /dev/null +++ b/thirdparty/flutter_image_compress/go/go.sum @@ -0,0 +1,42 @@ +github.com/Xuanwo/go-locale v0.2.0 h1:1N8SGG2VNpLl6VVa8ueZm3Nm+dxvk8ffY9aviKHl4IE= +github.com/Xuanwo/go-locale v0.2.0/go.mod h1:6qbT9M726OJgyiGZro2YwPmx63wQzlH+VvtjJWQoftw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-flutter-desktop/go-flutter v0.40.1 h1:4GC+9sc4jLxFoqLcHIGBNHdcF99ABC30g2q9iIQ+100= +github.com/go-flutter-desktop/go-flutter v0.40.1/go.mod h1:VNXgUO61Nxa9y/5jHQJFFuWVK9oNQF56MPKPUgQXwlU= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7 h1:SCYMcCJ89LjRGwEa0tRluNRiMjZHalQZrVrvTbPh+qw= +github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200420212212-258d9bec320e h1:8ywu4ELC/6owgOZlZx75CyYS5AYwUT2L+hzPModKvag= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200420212212-258d9bec320e/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= +github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/thirdparty/flutter_image_compress/go/import.go.tmpl b/thirdparty/flutter_image_compress/go/import.go.tmpl new file mode 100644 index 000000000..776aab43a --- /dev/null +++ b/thirdparty/flutter_image_compress/go/import.go.tmpl @@ -0,0 +1,13 @@ +package main + +// DO NOT EDIT, this file is generated by hover at compile-time for the flutter_image_compress plugin. + +import ( + flutter "github.com/go-flutter-desktop/go-flutter" + flutter_image_compress "github.com/openflutter/flutter_image_compress/go" +) + +func init() { + // Only the init function can be tweaked by plugin maker. + options = append(options, flutter.AddPlugin(&flutter_image_compress.FlutterImageCompressPlugin{})) +} diff --git a/thirdparty/flutter_image_compress/go/plugin.go b/thirdparty/flutter_image_compress/go/plugin.go new file mode 100644 index 000000000..4bcc8f9e1 --- /dev/null +++ b/thirdparty/flutter_image_compress/go/plugin.go @@ -0,0 +1,189 @@ +package flutter_image_compress + +import ( + "bytes" + "fmt" + "image" + "image/jpeg" + "image/png" + "io" + "os" + + "github.com/chai2010/webp" + flutter "github.com/go-flutter-desktop/go-flutter" + "github.com/go-flutter-desktop/go-flutter/plugin" +) + +const ( + channelName = "flutter_image_compress" + methodListToList = `compressWithList` + methodListToFile = `compressWithFile` + methodFileToFile = `compressWithFileAndGetFile` + methodLog = `showLog` + methodSystemVersion = `getSystemVersion` +) + +// FlutterImageCompressPlugin implements flutter.Plugin and handles method. +type FlutterImageCompressPlugin struct{} + +var _ flutter.Plugin = &FlutterImageCompressPlugin{} // compile-time type check + +// InitPlugin initializes the plugin. +func (p *FlutterImageCompressPlugin) InitPlugin(messenger plugin.BinaryMessenger) error { + channel := plugin.NewMethodChannel(messenger, channelName, plugin.StandardMethodCodec{}) + + channel.HandleFunc(methodListToList, listToList) + channel.HandleFunc(methodListToFile, listToFile) + channel.HandleFunc(methodFileToFile, fileToFile) + channel.HandleFunc(methodLog, showLog) + channel.HandleFunc(methodSystemVersion, getSystemVersion) + + return nil +} + +func showLog(arguments interface{}) (reply interface{}, err error) { + return nil, nil +} + +func encode(targetType int32, img image.Image, quality int, writer io.Writer) error { + switch targetType { + case 0: + return jpeg.Encode(writer, img, &jpeg.Options{Quality: quality}) + case 1: + return png.Encode(writer, img) + case 2: + return fmt.Errorf("Not support heic") + case 3: + return webp.Encode(writer, img, &webp.Options{ + Lossless: false, + Quality: float32(quality), + Exact: false, + }) + } + + return fmt.Errorf("Not support format") +} + +func listToList(arguments interface{}) (reply interface{}, err error) { + args := arguments.([]interface{}) + img := args[0].([]uint8) + minWidth := args[1].(int32) + minHeight := args[2].(int32) + quality := int(args[3].(int32)) + rotate := int(args[4].(int32)) + targetType := args[6].(int32) + + reader := bytes.NewReader(img) + + scaled, err := ScaleImage(reader, minWidth, minHeight) + if err != nil { + return + } + + scaled = RotateImage(scaled, rotate) + + writer := bytes.Buffer{} + + err = encode(targetType, scaled, quality, &writer) + if err != nil { + return + } + + reply = writer.Bytes() + + return +} + +func listToFile(arguments interface{}) (reply interface{}, err error) { + args := arguments.([]interface{}) + srcPath := args[0].(string) + minWidth := args[1].(int32) + minHeight := args[2].(int32) + quality := int(args[3].(int32)) + rotate := int(args[4].(int32)) + targetType := args[6].(int32) + + reader, err := os.Open(srcPath) + + if err != nil { + return + } + + scaled, err := ScaleImage(reader, minWidth, minHeight) + if err != nil { + return + } + + scaled = RotateImage(scaled, rotate) + + writer := bytes.Buffer{} + + err = encode(targetType, scaled, quality, &writer) + if err != nil { + return + } + + reply = writer.Bytes() + + return +} + +func fileToFile(arguments interface{}) (reply interface{}, err error) { + args := arguments.([]interface{}) + srcPath := args[0].(string) + minWidth := args[1].(int32) + minHeight := args[2].(int32) + quality := int(args[3].(int32)) + targetPath := args[4].(string) + rotate := int(args[5].(int32)) + targetType := args[7].(int32) + + reader, err := os.Open(srcPath) + + if err != nil { + return + } + + scaled, err := ScaleImage(reader, minWidth, minHeight) + if err != nil { + return + } + + scaled = RotateImage(scaled, rotate) + + exists, err := pathExists(targetPath) + if err != nil { + return + } + + if exists { + _ = os.Remove(targetPath) + } + + writer, _ := os.OpenFile(targetPath, os.O_RDWR|os.O_CREATE, 777) + + err = encode(targetType, scaled, quality, writer) + if err != nil { + return + } + + reply = targetPath + + return +} + +func getSystemVersion(arguments interface{}) (reply interface{}, err error) { + args := arguments.([]interface{}) + showAllArgsType(args) + panic("not implements") +} + +func typeof(v interface{}) string { + return fmt.Sprintf("%T", v) +} + +func showAllArgsType(args []interface{}) { + for i, v := range args { + fmt.Printf("%d, type = %s \n", i, typeof(v)) + } +} diff --git a/thirdparty/flutter_image_compress/ios/.gitignore b/thirdparty/flutter_image_compress/ios/.gitignore new file mode 100644 index 000000000..710ec6cf1 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/.gitignore @@ -0,0 +1,36 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig diff --git a/thirdparty/flutter_image_compress/ios/Assets/.gitkeep b/thirdparty/flutter_image_compress/ios/Assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/thirdparty/flutter_image_compress/ios/Classes/CompressFileHandler.h b/thirdparty/flutter_image_compress/ios/Classes/CompressFileHandler.h new file mode 100644 index 000000000..bd2147825 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/CompressFileHandler.h @@ -0,0 +1,12 @@ +// +// Created by cjl on 2018/9/8. +// + +#import +#import + +@interface CompressFileHandler : NSObject +- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result; + +- (void)handleCompressFileToFile:(FlutterMethodCall *)call result:(FlutterResult)result; +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/CompressFileHandler.m b/thirdparty/flutter_image_compress/ios/Classes/CompressFileHandler.m new file mode 100644 index 000000000..6e30b34d8 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/CompressFileHandler.m @@ -0,0 +1,147 @@ +// +// Created by cjl on 2018/9/8. +// + +#import "CompressFileHandler.h" +#import "CompressHandler.h" +#import "SYMetadata.h" +#import +#import + +@implementation CompressFileHandler { + +} +- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { + + NSArray *args = call.arguments; + NSString *path = args[0]; + int minWidth = [args[1] intValue]; + int minHeight = [args[2] intValue]; + int quality = [args[3] intValue]; + int rotate = [args[4] intValue]; + + int formatType = [args[6] intValue]; + BOOL keepExif = [args[7] boolValue]; + + + UIImage *img; + + NSURL *imageUrl = [NSURL fileURLWithPath:path]; + NSData *nsdata = [NSData dataWithContentsOfURL:imageUrl]; + + NSString *imageType = [self mimeTypeByGuessingFromData:nsdata]; + + // NSLog(@" nsdata length: %@", imageType); + + SDImageWebPCoder *webPCoder = [SDImageWebPCoder sharedCoder]; + // [[SDImageCodersManager sharedManager] addCoder:webPCoder]; + + if(imageType == @"image/webp") { + img = [[SDImageWebPCoder sharedCoder] decodedImageWithData:nsdata options:nil]; + } else { + img = [UIImage imageWithData:nsdata]; + } + + + NSData *data = [CompressHandler compressWithUIImage:img minWidth:minWidth minHeight:minHeight quality:quality rotate:rotate format:formatType]; + + if (keepExif) { + SYMetadata *metadata = [SYMetadata metadataWithFileURL:[NSURL fileURLWithPath:path]]; + metadata.orientation = @0; + data = [SYMetadata dataWithImageData:data andMetadata:metadata]; + } + + result([FlutterStandardTypedData typedDataWithBytes:data]); +} + +- (void)handleCompressFileToFile:(FlutterMethodCall *)call result:(FlutterResult)result { + NSArray *args = call.arguments; + NSString *path = args[0]; + int minWidth = [args[1] intValue]; + int minHeight = [args[2] intValue]; + int quality = [args[3] intValue]; + NSString *targetPath = args[4]; + int rotate = [args[5] intValue]; + + int formatType = [args[7] intValue]; + BOOL keepExif = [args[8] boolValue]; + + + UIImage *img; + + NSURL *imageUrl = [NSURL fileURLWithPath:path]; + NSData *nsdata = [NSData dataWithContentsOfURL:imageUrl]; + + NSString *imageType = [self mimeTypeByGuessingFromData:nsdata]; + + // NSLog(@" nsdata length: %@", imageType); + + SDImageWebPCoder *webPCoder = [SDImageWebPCoder sharedCoder]; + // [[SDImageCodersManager sharedManager] addCoder:webPCoder]; + + if(imageType == @"image/webp") { + img = [[SDImageWebPCoder sharedCoder] decodedImageWithData:nsdata options:nil]; + } else { + img = [UIImage imageWithData:nsdata]; + } + + NSData *data = [CompressHandler compressDataWithUIImage:img minWidth:minWidth minHeight:minHeight quality:quality rotate:rotate format:formatType]; + + if (keepExif) { + SYMetadata *metadata = [SYMetadata metadataWithFileURL:[NSURL fileURLWithPath:path]]; + metadata.orientation = @0; + data = [SYMetadata dataWithImageData:data andMetadata:metadata]; + } + + [data writeToURL:[[NSURL alloc] initFileURLWithPath:targetPath] atomically:YES]; + + result(targetPath); +} + + +- (NSString *)mimeTypeByGuessingFromData:(NSData *)data { + + char bytes[12] = {0}; + [data getBytes:&bytes length:12]; + + const char bmp[2] = {'B', 'M'}; + const char gif[3] = {'G', 'I', 'F'}; + const char swf[3] = {'F', 'W', 'S'}; + const char swc[3] = {'C', 'W', 'S'}; + const char jpg[3] = {0xff, 0xd8, 0xff}; + const char psd[4] = {'8', 'B', 'P', 'S'}; + const char iff[4] = {'F', 'O', 'R', 'M'}; + const char webp[4] = {'R', 'I', 'F', 'F'}; + const char ico[4] = {0x00, 0x00, 0x01, 0x00}; + const char tif_ii[4] = {'I','I', 0x2A, 0x00}; + const char tif_mm[4] = {'M','M', 0x00, 0x2A}; + const char png[8] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; + const char jp2[12] = {0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a}; + + + if (!memcmp(bytes, bmp, 2)) { + return @"image/x-ms-bmp"; + } else if (!memcmp(bytes, gif, 3)) { + return @"image/gif"; + } else if (!memcmp(bytes, jpg, 3)) { + return @"image/jpeg"; + } else if (!memcmp(bytes, psd, 4)) { + return @"image/psd"; + } else if (!memcmp(bytes, iff, 4)) { + return @"image/iff"; + } else if (!memcmp(bytes, webp, 4)) { + return @"image/webp"; + } else if (!memcmp(bytes, ico, 4)) { + return @"image/vnd.microsoft.icon"; + } else if (!memcmp(bytes, tif_ii, 4) || !memcmp(bytes, tif_mm, 4)) { + return @"image/tiff"; + } else if (!memcmp(bytes, png, 8)) { + return @"image/png"; + } else if (!memcmp(bytes, jp2, 12)) { + return @"image/jp2"; + } + + return @"application/octet-stream"; // default type + +} +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/CompressHandler.h b/thirdparty/flutter_image_compress/ios/Classes/CompressHandler.h new file mode 100644 index 000000000..6dc90cc49 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/CompressHandler.h @@ -0,0 +1,17 @@ +// +// Created by cjl on 2018/9/8. +// + +#import + + +@interface CompressHandler : NSObject ++ (NSData *)compressWithData:(NSData *)data minWidth:(int)minWidth minHeight:(int)minHeight quality:(int)quality + rotate:(int)rotate format:(int)format; + ++ (NSData *)compressWithUIImage:(UIImage *)image minWidth:(int)minWidth minHeight:(int)minHeight quality:(int)quality + rotate:(int)rotate format:(int)format; + ++ (NSData *)compressDataWithUIImage:(UIImage *)image minWidth:(int)minWidth minHeight:(int)minHeight + quality:(int)quality rotate:(int)rotate format:(int)format; +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/CompressHandler.m b/thirdparty/flutter_image_compress/ios/Classes/CompressHandler.m new file mode 100644 index 000000000..0554c8624 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/CompressHandler.m @@ -0,0 +1,83 @@ +// +// Created by cjl on 2018/9/8. +// + +#import "CompressHandler.h" +#import "UIImage+scale.h" +#import "FlutterImageCompressPlugin.h" +#import "SDImageWebPCoder.h" + +@implementation CompressHandler { + +} + ++ (NSData *)compressWithData:(NSData *)data minWidth:(int)minWidth minHeight:(int)minHeight quality:(int)quality + rotate:(int)rotate format:(int)format { + UIImage *img = [[UIImage alloc] initWithData:data]; + return [CompressHandler compressWithUIImage:img minWidth:minWidth minHeight:minHeight quality:quality rotate:rotate format:format]; +} + ++ (NSData *)compressWithUIImage:(UIImage *)image minWidth:(int)minWidth minHeight:(int)minHeight quality:(int)quality + rotate:(int)rotate format:(int)format { + if([FlutterImageCompressPlugin showLog]){ + NSLog(@"width = %.0f",[image size].width); + NSLog(@"height = %.0f",[image size].height); + NSLog(@"minWidth = %d",minWidth); + NSLog(@"minHeight = %d",minHeight); + NSLog(@"format = %d", format); + } + + image = [image scaleWithMinWidth:minWidth minHeight:minHeight]; + if(rotate % 360 != 0){ + image = [image rotate: rotate]; + } + NSData *resultData = [self compressDataWithImage:image quality:quality format:format]; + + return resultData; +} + + ++ (NSData *)compressDataWithUIImage:(UIImage *)image minWidth:(int)minWidth minHeight:(int)minHeight + quality:(int)quality rotate:(int)rotate format:(int)format { + image = [image scaleWithMinWidth:minWidth minHeight:minHeight]; + if(rotate % 360 != 0){ + image = [image rotate: rotate]; + } + return [self compressDataWithImage:image quality:quality format:format]; +} + ++ (NSData *)compressDataWithImage:(UIImage *)image quality:(float)quality format:(int)format { + NSData *data; + if (format == 2) { // heic + CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage]; + CIContext *ciContext = [[CIContext alloc]initWithOptions:nil]; + NSString *tmpDir = NSTemporaryDirectory(); + double time = [[NSDate alloc]init].timeIntervalSince1970; + NSString *target = [NSString stringWithFormat:@"%@%.0f.heic",tmpDir, time * 1000]; + NSURL *url = [NSURL fileURLWithPath:target]; + + NSMutableDictionary *options = [NSMutableDictionary new]; + NSString *qualityKey = (__bridge NSString *)kCGImageDestinationLossyCompressionQuality; +// CIImageRepresentationOption + [options setObject:@(quality / 100) forKey: qualityKey]; + + if (@available(iOS 11.0, *)) { + [ciContext writeHEIFRepresentationOfImage:ciImage toURL:url format: kCIFormatARGB8 colorSpace: ciImage.colorSpace options:options error:nil]; + data = [NSData dataWithContentsOfURL:url]; + } else { + // Fallback on earlier versions + data = nil; + } + } else if(format == 3){ // webp +/* SDImageCoderOptions *option = @{SDImageCoderEncodeCompressionQuality: @(quality / 100)}; + data = [[SDImageWebPCoder sharedCoder]encodedDataWithImage:image format:SDImageFormatWebP options:option]; */ + } else if(format == 1){ // png + data = UIImagePNGRepresentation(image); + }else { // 0 or other is jpeg + data = UIImageJPEGRepresentation(image, (CGFloat) quality / 100); + } + + return data; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/CompressListHandler.h b/thirdparty/flutter_image_compress/ios/Classes/CompressListHandler.h new file mode 100644 index 000000000..9aba711ea --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/CompressListHandler.h @@ -0,0 +1,13 @@ +// +// CompressListHandler.h +// flutter_image_compress +// +// Created by cjl on 2018/9/8. +// + +#import + +@interface CompressListHandler : NSObject + +- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result; +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/CompressListHandler.m b/thirdparty/flutter_image_compress/ios/Classes/CompressListHandler.m new file mode 100644 index 000000000..8f6057cbb --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/CompressListHandler.m @@ -0,0 +1,39 @@ +// +// CompressListHandler.m +// flutter_image_compress +// +// Created by cjl on 2018/9/8. +// + +#import +#import "CompressListHandler.h" +#import "CompressHandler.h" +#import "SYMetadata.h" + +@implementation CompressListHandler + +- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { + NSArray *args = call.arguments; + FlutterStandardTypedData *list = args[0]; + int minWidth = [args[1] intValue]; + int minHeight = [args[2] intValue]; + int quality = [args[3] intValue]; + int rotate = [args[4] intValue]; + int formatType = [args[6] intValue]; + + BOOL keepExif = [args[7] boolValue]; + + NSData *data = [list data]; + NSData *compressedData = [CompressHandler compressWithData:data minWidth:minWidth minHeight:minHeight quality:quality rotate:rotate format:formatType]; + + if (keepExif) { + SYMetadata *metadata = [SYMetadata metadataWithImageData:data]; + metadata.orientation = @0; + compressedData = [SYMetadata dataWithImageData:compressedData andMetadata:metadata]; + } + + result([FlutterStandardTypedData typedDataWithBytes:compressedData]); +} + + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/FlutterImageCompressPlugin.h b/thirdparty/flutter_image_compress/ios/Classes/FlutterImageCompressPlugin.h new file mode 100644 index 000000000..7588353cb --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/FlutterImageCompressPlugin.h @@ -0,0 +1,7 @@ +#import + +@interface FlutterImageCompressPlugin : NSObject + ++(BOOL) showLog; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/FlutterImageCompressPlugin.m b/thirdparty/flutter_image_compress/ios/Classes/FlutterImageCompressPlugin.m new file mode 100644 index 000000000..ce9821f33 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/FlutterImageCompressPlugin.m @@ -0,0 +1,52 @@ +#import "FlutterImageCompressPlugin.h" +#import "CompressListHandler.h" +#import "CompressFileHandler.h" + +BOOL showLog = false; + +@implementation FlutterImageCompressPlugin +static dispatch_queue_t serial_queue; + ++ (void)registerWithRegistrar:(NSObject *)registrar { + serial_queue = dispatch_get_global_queue(0, 0); + + FlutterMethodChannel *channel = [FlutterMethodChannel + methodChannelWithName:@"flutter_image_compress" + binaryMessenger:[registrar messenger]]; + FlutterImageCompressPlugin *instance = [[FlutterImageCompressPlugin alloc] init]; + [registrar addMethodCallDelegate:instance channel:channel]; +} + +- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { + dispatch_async(serial_queue, ^{ + if ([call.method isEqualToString:@"compressWithList"]) { + CompressListHandler *handler = [[CompressListHandler alloc] init]; + [handler handleMethodCall:call result:result]; + } else if ([@"compressWithFile" isEqualToString:call.method]) { + CompressFileHandler *handler = [[CompressFileHandler alloc] init]; + [handler handleMethodCall:call result:result]; + } else if ([@"compressWithFileAndGetFile" isEqualToString:call.method]) { + CompressFileHandler *handler = [[CompressFileHandler alloc] init]; + [handler handleCompressFileToFile:call result:result]; + } else if ([@"showLog" isEqualToString:call.method]) { + [self setShowLog:[call arguments]]; + result(@1); + } else if([@"getSystemVersion" isEqualToString:call.method]) { + NSString *systemVersion = [[UIDevice currentDevice] systemVersion]; + result(systemVersion); + } else { + result(FlutterMethodNotImplemented); + } + }); + +} + ++ (BOOL)showLog{ + return showLog; +} + +- (void)setShowLog:(BOOL)log{ + showLog = log; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/NSDictionary+SY.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/NSDictionary+SY.h new file mode 100755 index 000000000..783b89682 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/NSDictionary+SY.h @@ -0,0 +1,19 @@ +// +// NSDictionary+SY.h +// SYPictureMetadataExample +// +// Created by Stanislas Chevallier on 03/02/2017. +// Copyright © 2017 Syan. All rights reserved. +// + +#import + +@interface NSDictionary (SY) + ++ (NSDictionary *)sy_differencesFrom:(NSDictionary *)dictionaryOld + to:(NSDictionary *)dictionaryNew + includeValuesInDiff:(BOOL)includeValuesInDiff; + +- (NSArray *)sy_allKeypaths; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/NSDictionary+SY.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/NSDictionary+SY.m new file mode 100755 index 000000000..a0424c7e1 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/NSDictionary+SY.m @@ -0,0 +1,95 @@ +// +// NSDictionary+SY.m +// SYPictureMetadataExample +// +// Created by Stanislas Chevallier on 03/02/2017. +// Copyright © 2017 Syan. All rights reserved. +// + +#import "NSDictionary+SY.h" + +@implementation NSDictionary (SY) + ++ (NSDictionary *)sy_differencesFrom:(NSDictionary *)dictionaryOld + to:(NSDictionary *)dictionaryNew + includeValuesInDiff:(BOOL)includeValuesInDiff; +{ + NSString *formatAdded = (includeValuesInDiff ? @"Added: %@" : @"Added" ); + NSString *formatUpdated = (includeValuesInDiff ? @"Updated: %@ -> %@" : @"Updated"); + NSString *formatRemoved = (includeValuesInDiff ? @"Removed: %@" : @"Removed"); + + NSMutableSet *allKeys = [NSMutableSet set]; + [allKeys addObjectsFromArray:dictionaryOld.allKeys]; + [allKeys addObjectsFromArray:dictionaryNew.allKeys]; + + NSMutableDictionary *diffs = [[NSMutableDictionary alloc] init]; + for (id key in allKeys) + { + id valueOld = dictionaryOld[key]; + id valueNew = dictionaryNew[key]; + + if (valueOld && valueNew && [valueOld isEqual:valueNew]) + continue; + + BOOL oldIsNilOrDic = !valueOld || [valueOld isKindOfClass:[NSDictionary class]]; + BOOL newIsNilOrDic = !valueNew || [valueNew isKindOfClass:[NSDictionary class]]; + + if (oldIsNilOrDic && newIsNilOrDic) + { + NSDictionary *subDiffs = [self sy_differencesFrom:valueOld + to:valueNew + includeValuesInDiff:includeValuesInDiff]; + [diffs setObject:subDiffs forKey:key]; + continue; + } + + NSString *valueOldString = [valueOld description]; + NSString *valueNewString = [valueNew description]; + + if ([valueOld isKindOfClass:[NSArray class]]) + valueOldString = [valueOld componentsJoinedByString:@", "]; + if ([valueNew isKindOfClass:[NSArray class]]) + valueNewString = [valueNew componentsJoinedByString:@", "]; + + if ( valueOld && !valueNew) + { + [diffs setObject:[NSString stringWithFormat:formatRemoved, valueOldString] + forKey:key]; + continue; + } + + if (!valueOld && valueNew) + { + [diffs setObject:[NSString stringWithFormat:formatAdded, valueNewString] + forKey:key]; + continue; + } + + [diffs setObject:[NSString stringWithFormat:formatUpdated, valueOldString, valueNewString] + forKey:key]; + } + + return [diffs copy]; +} + +- (NSArray *)sy_allKeypaths +{ + NSMutableArray *keypaths = [NSMutableArray array]; + + for (id key in self.allKeys) + { + NSString *keyString = [key description]; + [keypaths addObject:keyString]; + + id value = self[key]; + if ([value isKindOfClass:[NSDictionary class]]) + { + for (NSString *subKeypath in [(NSDictionary *)value sy_allKeypaths]) + [keypaths addObject:[@[keyString, subKeypath] componentsJoinedByString:@"."]]; + } + } + + return [keypaths copy]; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata.h new file mode 100755 index 000000000..645525970 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata.h @@ -0,0 +1,86 @@ +// +// SYMetadata.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/13/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import +#import "SYMetadataTIFF.h" +#import "SYMetadataGIF.h" +#import "SYMetadataJFIF.h" +#import "SYMetadataExif.h" +#import "SYMetadataPNG.h" +#import "SYMetadataIPTC.h" +#import "SYMetadataGPS.h" +#import "SYMetadataRaw.h" +#import "SYMetadataCIFF.h" +#import "SYMetadataMakerCanon.h" +#import "SYMetadataMakerNikon.h" +#import "SYMetadataMakerMinolta.h" +#import "SYMetadataMakerFuji.h" +#import "SYMetadataMakerOlympus.h" +#import "SYMetadataMakerPentax.h" +#import "SYMetadata8BIM.h" +#import "SYMetadataDNG.h" +#import "SYMetadataExifAux.h" + +// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/index.html +// http://www.exiv2.org/tags.html + +@class ALAsset; + +@interface SYMetadata : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSDictionary *originalDictionary; + +@property SYMETADATA_PROPERTY_STRONG SYMetadataTIFF *metadataTIFF; +@property SYMETADATA_PROPERTY_STRONG SYMetadataExif *metadataExif; +@property SYMETADATA_PROPERTY_STRONG SYMetadataGIF *metadataGIF; +@property SYMETADATA_PROPERTY_STRONG SYMetadataJFIF *metadataJFIF; +@property SYMETADATA_PROPERTY_STRONG SYMetadataPNG *metadataPNG; +@property SYMETADATA_PROPERTY_STRONG SYMetadataIPTC *metadataIPTC; +@property SYMETADATA_PROPERTY_STRONG SYMetadataGPS *metadataGPS; +@property SYMETADATA_PROPERTY_STRONG SYMetadataRaw *metadataRaw; +@property SYMETADATA_PROPERTY_STRONG SYMetadataCIFF *metadataCIFF; +@property SYMETADATA_PROPERTY_STRONG SYMetadataMakerCanon *metadataMakerCanon; +@property SYMETADATA_PROPERTY_STRONG SYMetadataMakerNikon *metadataMakerNikon; +@property SYMETADATA_PROPERTY_STRONG SYMetadataMakerMinolta *metadataMakerMinolta; +@property SYMETADATA_PROPERTY_STRONG SYMetadataMakerFuji *metadataMakerFuji; +@property SYMETADATA_PROPERTY_STRONG SYMetadataMakerOlympus *metadataMakerOlympus; +@property SYMETADATA_PROPERTY_STRONG SYMetadataMakerPentax *metadataMakerPentax; +@property SYMETADATA_PROPERTY_STRONG SYMetadata8BIM *metadata8BIM; +@property SYMETADATA_PROPERTY_STRONG SYMetadataDNG *metadataDNG; +@property SYMETADATA_PROPERTY_STRONG SYMetadataExifAux *metadataExifAux; + +// we don't know how to parse those, so we juste give access to them +@property SYMETADATA_PROPERTY_COPY NSDictionary *metadataApple; +@property SYMETADATA_PROPERTY_COPY NSDictionary *metadataPictureStyle; + +@property (nonatomic, copy, readonly) NSNumber *fileSize; +@property (nonatomic, copy, readonly) NSNumber *pixelHeight; +@property (nonatomic, copy, readonly) NSNumber *pixelWidth; +@property (nonatomic, copy, readonly) NSNumber *dpiHeight; +@property (nonatomic, copy, readonly) NSNumber *dpiWidth; +@property (nonatomic, copy, readonly) NSNumber *depth; +@property SYMETADATA_PROPERTY_COPY NSNumber *orientation; +@property (nonatomic, copy, readonly) NSNumber *isFloat; +@property (nonatomic, copy, readonly) NSNumber *isIndexed; +@property (nonatomic, copy, readonly) NSNumber *hasAlpha; +@property (nonatomic, copy, readonly) NSString *colorModel; +@property (nonatomic, copy, readonly) NSString *profileName; + ++ (instancetype)metadataWithDictionary:(NSDictionary *)dictionary; ++ (instancetype)metadataWithAsset:(ALAsset *)asset __TVOS_PROHIBITED; ++ (instancetype)metadataWithAssetURL:(NSURL *)assetURL __TVOS_PROHIBITED; ++ (instancetype)metadataWithFileURL:(NSURL *)fileURL; ++ (instancetype)metadataWithImageData:(NSData *)imageData; + ++ (NSDictionary *)dictionaryWithAssetURL:(NSURL *)assetURL __TVOS_PROHIBITED; + ++ (NSData *)dataWithImageData:(NSData *)imageData andMetadata:(SYMetadata *)metadata; + +- (NSDictionary *)differencesFromOriginalMetadataToModel; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata.m new file mode 100755 index 000000000..c49ecf290 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata.m @@ -0,0 +1,263 @@ +// +// SYMetadata.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/13/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import +#import "SYMetadata.h" +#import "NSDictionary+SY.h" + +#if !TARGET_OS_TV +#import +#endif + +#define SYKeyForMetadata(name) NSStringFromSelector(@selector(metadata##name)) +#define SYDictionaryForMetadata(name) SYPaste(SYPaste(kCGImageProperty,name),Dictionary) +#define SYClassForMetadata(name) SYPaste(SYMetadata,name) +#define SYMappingPptyToClass(name) SYKeyForMetadata(name):SYClassForMetadata(name).class +#define SYMappingPptyToKeyPath(name) SYKeyForMetadata(name):(__bridge NSString *)SYDictionaryForMetadata(name) + +@interface SYMetadata (Private) +- (void)refresh:(BOOL)force; +@end + +@implementation SYMetadata + +#pragma mark - Initialization + ++ (instancetype)metadataWithDictionary:(NSDictionary *)dictionary +{ + if (!dictionary) + return nil; + + NSError *error; + + SYMetadata *instance = [MTLJSONAdapter modelOfClass:self.class fromJSONDictionary:dictionary error:&error]; + + if (instance) + instance->_originalDictionary = dictionary; + + if (error) + NSLog(@"--> Error creating %@ object: %@", NSStringFromClass(self.class), error); + + return instance; +} + ++ (instancetype)metadataWithAsset:(ALAsset *)asset +{ +#if !TARGET_OS_TV + ALAssetRepresentation *representation = [asset defaultRepresentation]; + return [self metadataWithDictionary:[representation metadata]]; +#else + return nil; +#endif +} + ++ (instancetype)metadataWithAssetURL:(NSURL *)assetURL +{ + NSDictionary *dictionary = [self dictionaryWithAssetURL:assetURL]; + return [self metadataWithDictionary:dictionary]; +} + ++ (instancetype)metadataWithFileURL:(NSURL *)fileURL +{ + if (!fileURL) + return nil; + + CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)fileURL, NULL); + if (source == NULL) + return nil; + + NSDictionary *dictionary; + + NSDictionary *options = @{(NSString *)kCGImageSourceShouldCache:@(NO)}; + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(source, 0, (__bridge CFDictionaryRef)options); + if (properties) { + dictionary = (__bridge NSDictionary*)properties; + } + + CFRelease(source); + + return [self metadataWithDictionary:dictionary]; +} + ++ (instancetype)metadataWithImageData:(NSData *)imageData +{ + if (!imageData.length) + return nil; + + CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL); + if (source == NULL) + return nil; + + NSDictionary *dictionary; + + NSDictionary *options = @{(NSString *)kCGImageSourceShouldCache:@(NO)}; + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(source, 0, (__bridge CFDictionaryRef)options); + if (properties) { + dictionary = (__bridge NSDictionary*)properties; + } + + CFRelease(source); + + return [self metadataWithDictionary:dictionary]; +} + +#pragma mark - Writing + +// https://github.com/Nikita2k/SimpleExif/blob/master/Classes/ios/UIImage%2BExif.m ++ (NSData *)dataWithImageData:(NSData *)imageData andMetadata:(SYMetadata *)metadata +{ + CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) imageData, NULL); + if (!source) { + NSLog(@"Error: Could not create image source"); + return nil; + } + + CFStringRef sourceImageType = CGImageSourceGetType(source); + + // create a new data object and write the new image into it + NSMutableData *data = [NSMutableData data]; + CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)data, sourceImageType, 1, NULL); + + if (!destination) { + NSLog(@"Error: Could not create image destination"); + CFRelease(source); + return nil; + } + + // add the image contained in the image source to the destination, overidding the old metadata with our modified metadata + CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)metadata.generatedDictionary); + BOOL success = CGImageDestinationFinalize(destination); + + if (!success) + NSLog(@"Error: Could not create data from image destination"); + + CFRelease(destination); + CFRelease(source); + + return (success ? data : nil); +} + +#pragma mark - Getting metadata + ++ (NSDictionary *)dictionaryWithAssetURL:(NSURL *)assetURL +{ +#if !TARGET_OS_TV + __block ALAsset *assetAtUrl = nil; + ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init]; + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + [library assetForURL:assetURL resultBlock:^(ALAsset *asset) { + assetAtUrl = asset; + dispatch_semaphore_signal(sema); + } failureBlock:^(NSError *error) { + dispatch_semaphore_signal(sema); + }]; + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + + if (!assetAtUrl) + return nil; + + ALAssetRepresentation *representation = [assetAtUrl defaultRepresentation]; + return [representation metadata]; +#else + return nil; +#endif +} + +#pragma mark - Mapping + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + NSMutableDictionary *mappings = [NSMutableDictionary dictionary]; + [mappings + addEntriesFromDictionary:@{SYMappingPptyToKeyPath(TIFF), + SYMappingPptyToKeyPath(Exif), + SYMappingPptyToKeyPath(GIF), + SYMappingPptyToKeyPath(JFIF), + SYMappingPptyToKeyPath(PNG), + SYMappingPptyToKeyPath(IPTC), + SYMappingPptyToKeyPath(GPS), + SYMappingPptyToKeyPath(Raw), + SYMappingPptyToKeyPath(CIFF), + SYMappingPptyToKeyPath(MakerCanon), + SYMappingPptyToKeyPath(MakerNikon), + SYMappingPptyToKeyPath(MakerMinolta), + SYMappingPptyToKeyPath(MakerFuji), + SYMappingPptyToKeyPath(MakerOlympus), + SYMappingPptyToKeyPath(MakerPentax), + SYMappingPptyToKeyPath(8BIM), + SYMappingPptyToKeyPath(DNG), + SYMappingPptyToKeyPath(ExifAux), + }]; + + [mappings + addEntriesFromDictionary:@{SYStringSel(fileSize): (NSString *)kCGImagePropertyFileSize, + SYStringSel(pixelHeight): (NSString *)kCGImagePropertyPixelHeight, + SYStringSel(pixelWidth): (NSString *)kCGImagePropertyPixelWidth, + SYStringSel(dpiHeight): (NSString *)kCGImagePropertyDPIHeight, + SYStringSel(dpiWidth): (NSString *)kCGImagePropertyDPIWidth, + SYStringSel(depth): (NSString *)kCGImagePropertyDepth, + SYStringSel(orientation): (NSString *)kCGImagePropertyOrientation, + SYStringSel(isFloat): (NSString *)kCGImagePropertyIsFloat, + SYStringSel(isIndexed): (NSString *)kCGImagePropertyIsIndexed, + SYStringSel(hasAlpha): (NSString *)kCGImagePropertyHasAlpha, + SYStringSel(colorModel): (NSString *)kCGImagePropertyColorModel, + SYStringSel(profileName): (NSString *)kCGImagePropertyProfileName, + + SYStringSel(metadataApple): (NSString *)kCGImagePropertyMakerAppleDictionary, + SYStringSel(metadataPictureStyle): (NSString *)kSYImagePropertyPictureStyle, + }]; + + return [mappings copy]; +} + ++ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key +{ + static dispatch_once_t onceToken; + static NSDictionary *classMappings; + dispatch_once(&onceToken, ^{ + classMappings = @{SYMappingPptyToClass(TIFF), + SYMappingPptyToClass(Exif), + SYMappingPptyToClass(GIF), + SYMappingPptyToClass(JFIF), + SYMappingPptyToClass(PNG), + SYMappingPptyToClass(IPTC), + SYMappingPptyToClass(GPS), + SYMappingPptyToClass(Raw), + SYMappingPptyToClass(CIFF), + SYMappingPptyToClass(MakerCanon), + SYMappingPptyToClass(MakerNikon), + SYMappingPptyToClass(MakerMinolta), + SYMappingPptyToClass(MakerFuji), + SYMappingPptyToClass(MakerOlympus), + SYMappingPptyToClass(MakerPentax), + SYMappingPptyToClass(8BIM), + SYMappingPptyToClass(DNG), + SYMappingPptyToClass(ExifAux), + }; + }); + + + Class objectClass = classMappings[key]; + + if (objectClass) + return [NSValueTransformer sy_dictionaryTransformerForModelOfClass:objectClass]; + + return [super JSONTransformerForKey:key]; +} + +#pragma mark - Tests + +- (NSDictionary *)differencesFromOriginalMetadataToModel +{ + return [NSDictionary sy_differencesFrom:self.originalDictionary + to:[self generatedDictionary] + includeValuesInDiff:YES]; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata8BIM.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata8BIM.h new file mode 100755 index 000000000..c161a37d3 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata8BIM.h @@ -0,0 +1,16 @@ +// +// SYMetadata8BIM.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadata8BIM : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSArray *layerNames; +@property SYMETADATA_PROPERTY_COPY NSNumber *version; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata8BIM.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata8BIM.m new file mode 100755 index 000000000..e7abc4df5 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadata8BIM.m @@ -0,0 +1,22 @@ +// +// SYMetadata8BIM.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadata8BIM.h" +#import + +@implementation SYMetadata8BIM + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(layerNames): (NSString *)kCGImageProperty8BIMLayerNames, + SYStringSel(version): (NSString *)kCGImageProperty8BIMVersion, + }; +} + +@end + diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataBase.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataBase.h new file mode 100755 index 000000000..6ed894e54 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataBase.h @@ -0,0 +1,42 @@ +// +// SYMetadataBase.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/13/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import +#import + +#define SYPaste1(a,b) a##b +#define SYPaste(a,b) SYPaste1(a,b) +#define SYStringSel(sel) NSStringFromSelector(@selector(sel)) + +// keys not available in public header, but still read by iOS +extern CFStringRef const kSYImagePropertyExifAuxAutoFocusInfo; +extern CFStringRef const kSYImagePropertyExifAuxImageStabilization; +extern CFStringRef const kSYImagePropertyCIFFMaxAperture; +extern CFStringRef const kSYImagePropertyCIFFMinAperture; +extern CFStringRef const kSYImagePropertyCIFFUniqueModelID; +extern CFStringRef const kSYImagePropertyPictureStyle; + +// allows to easily switch between read-only and R/W properties +#define SYMETADATA_PROPERTY_COPY (nonatomic, copy) +#define SYMETADATA_PROPERTY_STRONG (nonatomic, strong) + +@interface MTLValueTransformer (SY) ++ (instancetype)sy_nonZeroIntegerValueTransformer; +@end + +@interface NSValueTransformer (SY) ++ (instancetype)sy_dictionaryTransformerForModelOfClass:(Class)modelClass; +- (Class)sy_dictionaryTransformerModelClass; +@end + +@interface SYMetadataBase : MTLModel + +- (NSDictionary *)generatedDictionary; ++ (NSArray *)supportedKeys; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataBase.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataBase.m new file mode 100755 index 000000000..c8637742e --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataBase.m @@ -0,0 +1,167 @@ +// +// SYMetadataBase.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/13/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" +#import +#import + +#if TARGET_IPHONE_SIMULATOR && __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 +// keys needed for simulator < 9.0 +//CFStringRef const kCGImagePropertyAPNGDelayTime = CFSTR("DelayTime"); +//CFStringRef const kCGImagePropertyAPNGLoopCount = CFSTR("LoopCount"); +//CFStringRef const kCGImagePropertyAPNGUnclampedDelayTime = CFSTR("UnclampedDelayTime"); +CFStringRef const kCGImagePropertyMakerFujiDictionary = CFSTR("{MakerFuji}"); +CFStringRef const kCGImagePropertyMakerMinoltaDictionary = CFSTR("{MakerMinolta}"); +CFStringRef const kCGImagePropertyMakerOlympusDictionary = CFSTR("{MakerOlympus}"); +CFStringRef const kCGImagePropertyMakerPentaxDictionary = CFSTR("{MakerPentax}"); +#endif + +#if TARGET_IPHONE_SIMULATOR && __IPHONE_OS_VERSION_MIN_REQUIRED < 100000 +// keys needed for simulator < 10.0 +CFStringRef const kCGImageProperty8BIMVersion = CFSTR("Version"); +#endif + +#if !TARGET_IPHONE_SIMULATOR && __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 +// keys available since iOS 8+, exported here for < 8.0 +CFStringRef const kCGImagePropertyGPSHPositioningError = CFSTR("HPositioningError"); +#endif + +#if !TARGET_IPHONE_SIMULATOR && __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 +// keys available since iOS 9+, exported here for < 9.0 +CFStringRef const kCGImagePropertyTIFFTileWidth = CFSTR("TileWidth"); +CFStringRef const kCGImagePropertyTIFFTileLength = CFSTR("TileLength"); +CFStringRef const kCGImagePropertyPNGCompressionFilter = CFSTR("kCGImagePropertyPNGCompressionFilter"); +// keys available since iOS 8+ according to header, but not actually available... +//CFStringRef const kCGImagePropertyAPNGDelayTime = CFSTR("DelayTime"); +//CFStringRef const kCGImagePropertyAPNGLoopCount = CFSTR("LoopCount"); +//CFStringRef const kCGImagePropertyAPNGUnclampedDelayTime = CFSTR("UnclampedDelayTime"); +#endif + +#if !TARGET_IPHONE_SIMULATOR && __IPHONE_OS_VERSION_MIN_REQUIRED < 100000 +// keys available since iOS 8+ according to header, but not actually available... +CFStringRef const kCGImageProperty8BIMVersion = CFSTR("Version"); +// keys available since iOS 10+, exported here for < 10.0 +CFStringRef const kCGImagePropertyDNGBlackLevel = CFSTR("BlackLevel"); +CFStringRef const kCGImagePropertyDNGWhiteLevel = CFSTR("WhiteLevel"); +CFStringRef const kCGImagePropertyDNGCalibrationIlluminant1 = CFSTR("CalibrationIlluminant1"); +CFStringRef const kCGImagePropertyDNGCalibrationIlluminant2 = CFSTR("CalibrationIlluminant2"); +CFStringRef const kCGImagePropertyDNGColorMatrix1 = CFSTR("ColorMatrix1"); +CFStringRef const kCGImagePropertyDNGColorMatrix2 = CFSTR("ColorMatrix2"); +CFStringRef const kCGImagePropertyDNGCameraCalibration1 = CFSTR("CameraCalibration1"); +CFStringRef const kCGImagePropertyDNGCameraCalibration2 = CFSTR("CameraCalibration2"); +CFStringRef const kCGImagePropertyDNGAsShotNeutral = CFSTR("AsShotNeutral"); +CFStringRef const kCGImagePropertyDNGAsShotWhiteXY = CFSTR("AsShotWhiteXY"); +CFStringRef const kCGImagePropertyDNGBaselineExposure = CFSTR("BaselineExposure"); +CFStringRef const kCGImagePropertyDNGBaselineNoise = CFSTR("BaselineNoise"); +CFStringRef const kCGImagePropertyDNGBaselineSharpness = CFSTR("BaselineSharpness"); +CFStringRef const kCGImagePropertyDNGPrivateData = CFSTR("DNGPrivateData"); +CFStringRef const kCGImagePropertyDNGCameraCalibrationSignature = CFSTR("CameraCalibrationSignature"); +CFStringRef const kCGImagePropertyDNGProfileCalibrationSignature= CFSTR("ProfileCalibrationSignature"); +CFStringRef const kCGImagePropertyDNGNoiseProfile = CFSTR("NoiseProfile"); +CFStringRef const kCGImagePropertyDNGWarpRectilinear = CFSTR("WarpRectilinear"); +CFStringRef const kCGImagePropertyDNGWarpFisheye = CFSTR("WarpFisheye"); +CFStringRef const kCGImagePropertyDNGFixVignetteRadial = CFSTR("FixVignetteRadial"); +#endif + +// not defined in ImageIO but still read by iOS +CFStringRef const kSYImagePropertyPictureStyle = CFSTR("{PictureStyle}"); +CFStringRef const kSYImagePropertyExifAuxAutoFocusInfo = CFSTR("AFInfo"); +CFStringRef const kSYImagePropertyExifAuxImageStabilization = CFSTR("ImageStabilization"); +CFStringRef const kSYImagePropertyCIFFMaxAperture = CFSTR("MaxAperture"); +CFStringRef const kSYImagePropertyCIFFMinAperture = CFSTR("MinAperture"); +CFStringRef const kSYImagePropertyCIFFUniqueModelID = CFSTR("UniqueModelID"); + +@implementation SYMetadataBase + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{}; +} + ++ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key +{ + // default transformer to prevents NSNull in generated dictionary + return [MTLValueTransformer transformerUsingForwardBlock:^id(id value, BOOL *success, NSError *__autoreleasing *error) { + return value; + } reverseBlock:^id(id value, BOOL *success, NSError *__autoreleasing *error) { + return value; + }]; +} + ++ (NSArray *)supportedKeys +{ + NSMutableArray *keys = [NSMutableArray array]; + + NSDictionary *mappings = [self JSONKeyPathsByPropertyKey]; + for (NSString *key in mappings) + { + [keys addObject:mappings[key]]; + + NSValueTransformer *transformer = [self JSONTransformerForKey:key]; + Class modelClass = [transformer sy_dictionaryTransformerModelClass]; + + if ([(NSObject *)modelClass respondsToSelector:@selector(supportedKeys)]) + { + NSArray *subkeys = [modelClass supportedKeys]; + for (NSString *subkey in subkeys) + [keys addObject:[@[mappings[key], subkey] componentsJoinedByString:@"."]]; + } + } + + return [keys copy]; +} + +- (NSDictionary *)generatedDictionary +{ + NSError *error; + NSMutableDictionary *dictionary = [[MTLJSONAdapter JSONDictionaryFromModel:self error:&error] mutableCopy]; + + if (error) + NSLog(@"--> Error for class %@: %@", NSStringFromClass(self.class), error); + + [dictionary removeObjectsForKeys:[dictionary allKeysForObject:[NSNull null]]]; + return [dictionary copy]; +} + +@end + +@implementation MTLValueTransformer (SY) + ++ (instancetype)sy_nonZeroIntegerValueTransformer +{ + return [MTLValueTransformer transformerUsingForwardBlock:^id(id value, BOOL *success, NSError *__autoreleasing *error) { + return value; + } reverseBlock:^id(id value, BOOL *success, NSError *__autoreleasing *error) { + if ([value integerValue] == 0) + return nil; + return value; + }]; +} + +@end + +@implementation NSValueTransformer (SY) + ++ (instancetype)sy_dictionaryTransformerForModelOfClass:(Class)modelClass +{ + NSValueTransformer *instance = [MTLJSONAdapter dictionaryTransformerWithModelClass:modelClass]; + + if (instance) + objc_setAssociatedObject(instance, @selector(sy_dictionaryTransformerModelClass), NSStringFromClass(modelClass), OBJC_ASSOCIATION_COPY); + + return instance; +} + +- (Class)sy_dictionaryTransformerModelClass +{ + NSString *classString = objc_getAssociatedObject(self, @selector(sy_dictionaryTransformerModelClass)); + return (classString ? NSClassFromString(classString) : nil); +} + +@end + diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataCIFF.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataCIFF.h new file mode 100755 index 000000000..5fda62985 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataCIFF.h @@ -0,0 +1,40 @@ +// +// SYMetadataCIFF.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +// https://raw.githubusercontent.com/wiki/drewnoakes/metadata-extractor/docs/CIFFspecV1R04.pdf + +@interface SYMetadataCIFF : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSString *descr; +@property SYMETADATA_PROPERTY_COPY NSString *firmware; +@property SYMETADATA_PROPERTY_COPY NSString *ownerName; +@property SYMETADATA_PROPERTY_COPY NSString *imageName; +@property SYMETADATA_PROPERTY_COPY NSString *imageFileName; +@property SYMETADATA_PROPERTY_COPY NSNumber *releaseMethod; +@property SYMETADATA_PROPERTY_COPY NSNumber *releaseTiming; +@property SYMETADATA_PROPERTY_COPY NSNumber *recordID; +@property SYMETADATA_PROPERTY_COPY NSNumber *selfTimingTime; +@property SYMETADATA_PROPERTY_COPY NSNumber *cameraSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *imageSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *continuousDrive; +@property SYMETADATA_PROPERTY_COPY NSNumber *focusMode; +@property SYMETADATA_PROPERTY_COPY NSNumber *meteringMode; +@property SYMETADATA_PROPERTY_COPY NSNumber *shootingMode; +@property SYMETADATA_PROPERTY_COPY NSString *lensModel; +@property SYMETADATA_PROPERTY_COPY NSNumber *lensMaxMM; +@property SYMETADATA_PROPERTY_COPY NSNumber *lensMinMM; +@property SYMETADATA_PROPERTY_COPY NSNumber *whiteBalanceIndex; +@property SYMETADATA_PROPERTY_COPY NSNumber *flashExposureComp; +@property SYMETADATA_PROPERTY_COPY NSNumber *measuredEV; +@property SYMETADATA_PROPERTY_COPY NSNumber *uniqueModelID; +@property SYMETADATA_PROPERTY_COPY NSNumber *maxAperture; +@property SYMETADATA_PROPERTY_COPY NSNumber *minAperture; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataCIFF.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataCIFF.m new file mode 100755 index 000000000..18a42fc84 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataCIFF.m @@ -0,0 +1,44 @@ +// +// SYMetadataCIFF.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataCIFF.h" +#import + +@implementation SYMetadataCIFF + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(descr): (NSString *)kCGImagePropertyCIFFDescription, + SYStringSel(firmware): (NSString *)kCGImagePropertyCIFFFirmware, + SYStringSel(ownerName): (NSString *)kCGImagePropertyCIFFOwnerName, + SYStringSel(imageName): (NSString *)kCGImagePropertyCIFFImageName, + SYStringSel(imageFileName): (NSString *)kCGImagePropertyCIFFImageFileName, + SYStringSel(releaseMethod): (NSString *)kCGImagePropertyCIFFReleaseMethod, + SYStringSel(releaseTiming): (NSString *)kCGImagePropertyCIFFReleaseTiming, + SYStringSel(recordID): (NSString *)kCGImagePropertyCIFFRecordID, + SYStringSel(selfTimingTime): (NSString *)kCGImagePropertyCIFFSelfTimingTime, + SYStringSel(cameraSerialNumber): (NSString *)kCGImagePropertyCIFFCameraSerialNumber, + SYStringSel(imageSerialNumber): (NSString *)kCGImagePropertyCIFFImageSerialNumber, + SYStringSel(continuousDrive): (NSString *)kCGImagePropertyCIFFContinuousDrive, + SYStringSel(focusMode): (NSString *)kCGImagePropertyCIFFFocusMode, + SYStringSel(meteringMode): (NSString *)kCGImagePropertyCIFFMeteringMode, + SYStringSel(shootingMode): (NSString *)kCGImagePropertyCIFFShootingMode, + SYStringSel(lensModel): (NSString *)kCGImagePropertyCIFFLensModel, + SYStringSel(lensMaxMM): (NSString *)kCGImagePropertyCIFFLensMaxMM, + SYStringSel(lensMinMM): (NSString *)kCGImagePropertyCIFFLensMinMM, + SYStringSel(whiteBalanceIndex): (NSString *)kCGImagePropertyCIFFWhiteBalanceIndex, + SYStringSel(flashExposureComp): (NSString *)kCGImagePropertyCIFFFlashExposureComp, + SYStringSel(measuredEV): (NSString *)kCGImagePropertyCIFFMeasuredEV, + + SYStringSel(maxAperture): (NSString *)kSYImagePropertyCIFFMaxAperture, + SYStringSel(minAperture): (NSString *)kSYImagePropertyCIFFMinAperture, + SYStringSel(uniqueModelID): (NSString *)kSYImagePropertyCIFFUniqueModelID, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataDNG.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataDNG.h new file mode 100755 index 000000000..3a1ae7a03 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataDNG.h @@ -0,0 +1,42 @@ +// +// SYMetadataDNG.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +// https://www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf +@interface SYMetadataDNG : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSArray *version; +@property SYMETADATA_PROPERTY_COPY NSArray *backwardVersion; +@property SYMETADATA_PROPERTY_COPY NSString *uniqueCameraModel; +@property SYMETADATA_PROPERTY_COPY NSString *localizedCameraModel; +@property SYMETADATA_PROPERTY_COPY NSString *cameraSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSArray *lensInfo; + +@property SYMETADATA_PROPERTY_COPY NSArray *blackLevel; +@property SYMETADATA_PROPERTY_COPY NSArray *whiteLevel; +@property SYMETADATA_PROPERTY_COPY NSNumber *calibrationIlluminant1; +@property SYMETADATA_PROPERTY_COPY NSNumber *calibrationIlluminant2; +@property SYMETADATA_PROPERTY_COPY NSArray *colorMatrix1; +@property SYMETADATA_PROPERTY_COPY NSArray *colorMatrix2; +@property SYMETADATA_PROPERTY_COPY NSArray *cameraCalibration1; +@property SYMETADATA_PROPERTY_COPY NSArray *cameraCalibration2; +@property SYMETADATA_PROPERTY_COPY NSArray *asShotNeutral; +@property SYMETADATA_PROPERTY_COPY NSArray *asShotWhiteXY; +@property SYMETADATA_PROPERTY_COPY NSNumber *baselineExposure; +@property SYMETADATA_PROPERTY_COPY NSNumber *baselineNoise; +@property SYMETADATA_PROPERTY_COPY NSNumber *baselineSharpness; +@property SYMETADATA_PROPERTY_COPY NSObject *privateData; +@property SYMETADATA_PROPERTY_COPY NSString *cameraCalibrationSignature; +@property SYMETADATA_PROPERTY_COPY NSString *profileCalibrationSignature; +@property SYMETADATA_PROPERTY_COPY NSArray *noiseProfile; +@property SYMETADATA_PROPERTY_COPY NSArray *warpRectilinear; +@property SYMETADATA_PROPERTY_COPY NSArray *warpFisheye; +@property SYMETADATA_PROPERTY_COPY NSArray *fixVignetteRadial; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataDNG.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataDNG.m new file mode 100755 index 000000000..0b8323869 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataDNG.m @@ -0,0 +1,27 @@ +// +// SYMetadataDNG.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataDNG.h" +#import + +@implementation SYMetadataDNG + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(version): (NSString *)kCGImagePropertyDNGVersion, + SYStringSel(backwardVersion): (NSString *)kCGImagePropertyDNGBackwardVersion, + SYStringSel(uniqueCameraModel): (NSString *)kCGImagePropertyDNGUniqueCameraModel, + SYStringSel(localizedCameraModel): (NSString *)kCGImagePropertyDNGLocalizedCameraModel, + SYStringSel(cameraSerialNumber): (NSString *)kCGImagePropertyDNGCameraSerialNumber, + SYStringSel(lensInfo): (NSString *)kCGImagePropertyDNGLensInfo, + + + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExif.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExif.h new file mode 100755 index 000000000..c471f95e6 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExif.h @@ -0,0 +1,242 @@ +// +// SYMetadataExif.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/13/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import +#import "SYMetadataBase.h" + +typedef enum { + SYPictureExifExposureProgram_NotDefined = 0, + SYPictureExifExposureProgram_Manual = 1, + SYPictureExifExposureProgram_NormalProgram = 2, + SYPictureExifExposureProgram_AperturePriority = 3, + SYPictureExifExposureProgram_ShutterPriority = 4, + SYPictureExifExposureProgram_CreativeProgram = 5, // (biased toward depth of field) + SYPictureExifExposureProgram_ActionProgram = 6, // (biased toward fast shutter speed) + SYPictureExifExposureProgram_PortraitMode = 7, // (for closeup photos with the background out of focus) + SYPictureExifExposureProgram_LandscapeMode = 8 // (for landscape photos with the background in focus) +} SYPictureExifExposureProgram; + +typedef enum { + SYPictureExifMeteringMode_Unknown = 0, + SYPictureExifMeteringMode_Average = 1, + SYPictureExifMeteringMode_CenterWeightedAverage = 2, + SYPictureExifMeteringMode_Spot = 3, + SYPictureExifMeteringMode_MultiSpot = 4, + SYPictureExifMeteringMode_Pattern = 5, + SYPictureExifMeteringMode_Partial = 6, + SYPictureExifMeteringMode_Other = 255 +} SYPictureExifMeteringMode; + +typedef enum { + SYPictureExifLightSource_Unknown = 0, + SYPictureExifLightSource_Daylight = 1, + SYPictureExifLightSource_Fluorescent = 2, + SYPictureExifLightSource_TungstenIncandescentLight = 3, + SYPictureExifLightSource_Flash = 4, + SYPictureExifLightSource_FineWeather = 9, + SYPictureExifLightSource_CloudyWeather = 10, + SYPictureExifLightSource_Shade = 11, + SYPictureExifLightSource_DaylightFluorescent = 12, // (D 5700 - 7100K) + SYPictureExifLightSource_DayWhiteFluorescent = 13, // (N 4600 - 5400K) + SYPictureExifLightSource_CoolWhiteFluorescent = 14, // (W 3900 - 4500K) + SYPictureExifLightSource_WhiteFluorescent = 15, // (WW 3200 - 3700K) + SYPictureExifLightSource_StandardLightA = 17, + SYPictureExifLightSource_StandardLightB = 18, + SYPictureExifLightSource_StandardLightC = 19, + SYPictureExifLightSource_D55 = 20, + SYPictureExifLightSource_D65 = 21, + SYPictureExifLightSource_D75 = 22, + SYPictureExifLightSource_D50 = 23, + SYPictureExifLightSource_ISOStudioTungsten = 24, + SYPictureExifLightSource_OtherLightSource = 255 +} SYPictureExifLightSource; + +typedef enum { + SYPictureExifFocalPlaneResolutionUnit_NoAbsoluteUnitOfMeasurement = 1, + SYPictureExifFocalPlaneResolutionUnit_Inch = 2, + SYPictureExifFocalPlaneResolutionUnit_Centimeter = 3 +} SYPictureExifFocalPlaneResolutionUnit; + +typedef enum { + SYPictureExifSensingMethod_NotDefined = 1, + SYPictureExifSensingMethod_OneChipColorAreaSensor = 2, + SYPictureExifSensingMethod_TwoChipColorAreaSensor = 3, + SYPictureExifSensingMethod_ThreeChipColorAreaSensor = 4, + SYPictureExifSensingMethod_ColorSequentialAreaSensor = 5, + SYPictureExifSensingMethod_TrilinearSensor = 7, + SYPictureExifSensingMethod_ColorSequentialLinearSensor = 8 +} SYPictureExifSensingMethod; + +typedef enum { + SYPictureExifCustomRendered_NormalProcess = 0, + SYPictureExifCustomRendered_CustomProcess = 1 +} SYPictureExifCustomRendered; + +typedef enum { + SYPictureExifExposureMode_AutoExposure = 0, + SYPictureExifExposureMode_ManualExposure = 1, + SYPictureExifExposureMode_AutoBracket = 2 +} SYPictureExifExposureMode; + +typedef enum { + SYPictureExifWhiteBalance_Auto = 0, + SYPictureExifWhiteBalance_Manual = 1 +} SYPictureExifWhiteBalance; + +typedef enum { + SYPictureExifSceneCaptureType_Standard = 0, + SYPictureExifSceneCaptureType_Landscape = 1, + SYPictureExifSceneCaptureType_Portrait = 2, + SYPictureExifSceneCaptureType_NightScene = 3 +} SYPictureExifSceneCaptureType; + +typedef enum { + SYPictureExifGainControl_None = 0, + SYPictureExifGainControl_LowGainUp = 1, + SYPictureExifGainControl_HighGainUp = 2, + SYPictureExifGainControl_LowGainDown = 3, + SYPictureExifGainControl_HighGainDown = 4 +} SYPictureExifGainControl; + +typedef enum { + SYPictureExifContrast_Normal = 0, + SYPictureExifContrast_Soft = 1, + SYPictureExifContrast_Hard = 2 +} SYPictureExifContrast; + +typedef enum { + SYPictureExifSaturation_Normal = 0, + SYPictureExifSaturation_LowSaturation = 1, + SYPictureExifSaturation_HighSaturation = 2 +} SYPictureExifSaturation; + +typedef enum { + SYPictureExifSharpness_Normal = 0, + SYPictureExifSharpness_Soft = 1, + SYPictureExifSharpness_Hard = 2 +} SYPictureExifSharpness; + +typedef enum { + SYPictureExifSubjectDistanceRange_Unknown = 0, + SYPictureExifSubjectDistanceRange_Macro = 1, + SYPictureExifSubjectDistanceRange_CloseView = 2, + SYPictureExifSubjectDistanceRange_DistantView = 3 +} SYPictureExifSubjectDistanceRange; + +typedef enum : NSUInteger { + SYMetadataExifSensitivityType_Unknown = 0, + SYMetadataExifSensitivityType_StandardOutputSensitivity = 1, + SYMetadataExifSensitivityType_RecommendedExposureIndex = 2, + SYMetadataExifSensitivityType_ISOSpeed = 3, + SYMetadataExifSensitivityType_StandardOutputSensitivityAndRecommendedExposureIndex = 4, + SYMetadataExifSensitivityType_StandardOutputSensitivityAndISOSpeed = 5, + SYMetadataExifSensitivityType_RecommendedExposureIndexAndISOSpeed = 6, + SYMetadataExifSensitivityType_StandardOutputSensitivityAndRecommendedExposureIndexAndISOSpeed = 7, +} SYMetadataExifSensitivityType; + +typedef enum : NSUInteger { + SYMetadataExifFlash_FlashDidNotFire = 0x0000, + SYMetadataExifFlash_FlashFired = 0x0001, + SYMetadataExifFlash_StrobeReturnLightNotDetected = 0x0005, + SYMetadataExifFlash_StrobeReturnLightDetected = 0x0007, + SYMetadataExifFlash_FlashFiredCompulsoryFlashMode = 0x0009, + SYMetadataExifFlash_FlashFiredCompulsoryFlashModeReturnLightNotDetected = 0x000D, + SYMetadataExifFlash_FlashFiredCompulsoryFlashModeReturnLightDetected = 0x000F, + SYMetadataExifFlash_FlashDidNotFireCompulsoryDlashMode = 0x0010, + SYMetadataExifFlash_FlashDidNotFireAutoMode = 0x0018, + SYMetadataExifFlash_FlashFiredAutoMode = 0x0019, + SYMetadataExifFlash_FlashFiredAutoModeReturnLightNotDetected = 0x001D, + SYMetadataExifFlash_FlashFiredAutoModeReturnLightDetected = 0x001F, + SYMetadataExifFlash_NoFlashFunction = 0x0020, + SYMetadataExifFlash_FlashFiredRedEyeReductionMode = 0x0041, + SYMetadataExifFlash_FlashFiredRedEyeReductionModeReturnLightNotDetected = 0x0045, + SYMetadataExifFlash_FlashFiredRedEyeReductionModeReturnLightDetected = 0x0047, + SYMetadataExifFlash_FlashFiredCompulsoryFlashModeRedEyeReductionMode = 0x0049, + SYMetadataExifFlash_FlashFiredCompulsoryFlashModeRedEyeReductionModeReturnLightNotDetected = 0x004D, + SYMetadataExifFlash_FlashFiredCompulsoryFlashModeRedEyeReductionModeReturnLightDetected = 0x004F, + SYMetadataExifFlash_FlashFiredAutoModeRedEyeReductionMode = 0x0059, + SYMetadataExifFlash_FlashFiredAutoModeReturnLightNotDetectedRedEyeReductionMode = 0x005D, + SYMetadataExifFlash_FlashFiredAutoModeReturnLightDetectedRedEyeReductionMode = 0x005F, +} SYMetadataExifFlash; + +@interface SYMetadataExif : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSNumber *exposureTime; +@property SYMETADATA_PROPERTY_COPY NSNumber *fNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *exposureProgram; +@property SYMETADATA_PROPERTY_COPY NSString *spectralSensitivity; +@property SYMETADATA_PROPERTY_COPY NSArray *isoSpeedRatings; +@property SYMETADATA_PROPERTY_COPY NSObject *oecf; +@property SYMETADATA_PROPERTY_COPY NSArray *version; +@property SYMETADATA_PROPERTY_COPY NSString *dateTimeOriginal; +@property SYMETADATA_PROPERTY_COPY NSString *dateTimeDigitized; +@property SYMETADATA_PROPERTY_COPY NSArray *componentsConfiguration; +@property SYMETADATA_PROPERTY_COPY NSNumber *compressedBitsPerPixel; +@property SYMETADATA_PROPERTY_COPY NSNumber *shutterSpeedValue; +@property SYMETADATA_PROPERTY_COPY NSNumber *apertureValue; +@property SYMETADATA_PROPERTY_COPY NSNumber *brightnessValue; +@property SYMETADATA_PROPERTY_COPY NSNumber *exposureBiasValue; +@property SYMETADATA_PROPERTY_COPY NSNumber *maxApertureValue; +@property SYMETADATA_PROPERTY_COPY NSNumber *subjectDistance; +@property SYMETADATA_PROPERTY_COPY NSNumber *meteringMode; +@property SYMETADATA_PROPERTY_COPY NSNumber *lightSource; +@property SYMETADATA_PROPERTY_COPY NSNumber *flash; +@property SYMETADATA_PROPERTY_COPY NSString *flashString; +@property SYMETADATA_PROPERTY_COPY NSNumber *focalLength; +@property SYMETADATA_PROPERTY_COPY NSArray *subjectArea; +@property SYMETADATA_PROPERTY_COPY NSObject *makerNote; +@property SYMETADATA_PROPERTY_COPY NSString *userComment; +@property SYMETADATA_PROPERTY_COPY NSString *subsecTime; +@property SYMETADATA_PROPERTY_COPY NSString *subsecTimeOriginal; +@property SYMETADATA_PROPERTY_COPY NSString *subsecTimeDigitized; +@property SYMETADATA_PROPERTY_COPY NSArray *flashPixVersion; +@property SYMETADATA_PROPERTY_COPY NSNumber *colorSpace; +@property SYMETADATA_PROPERTY_COPY NSNumber *pixelXDimension; +@property SYMETADATA_PROPERTY_COPY NSNumber *pixelYDimension; +@property SYMETADATA_PROPERTY_COPY NSString *relatedSoundFile; +@property SYMETADATA_PROPERTY_COPY NSNumber *flashEnergy; +@property SYMETADATA_PROPERTY_COPY NSObject *spatialFrequencyResponse; +@property SYMETADATA_PROPERTY_COPY NSNumber *focalPlaneXResolution; +@property SYMETADATA_PROPERTY_COPY NSNumber *focalPlaneYResolution; +@property SYMETADATA_PROPERTY_COPY NSNumber *focalPlaneResolutionUnit; +@property SYMETADATA_PROPERTY_COPY NSArray *subjectLocation; +@property SYMETADATA_PROPERTY_COPY NSNumber *exposureIndex; +@property SYMETADATA_PROPERTY_COPY NSNumber *sensingMethod; +@property SYMETADATA_PROPERTY_COPY NSObject *fileSource; +@property SYMETADATA_PROPERTY_COPY NSObject *sceneType; +@property SYMETADATA_PROPERTY_COPY NSArray *cfaPattern; +@property SYMETADATA_PROPERTY_COPY NSNumber *customRendered; +@property SYMETADATA_PROPERTY_COPY NSNumber *exposureMode; +@property SYMETADATA_PROPERTY_COPY NSNumber *whiteBalance; +@property SYMETADATA_PROPERTY_COPY NSNumber *digitalZoomRatio; +@property SYMETADATA_PROPERTY_COPY NSNumber *focalLenIn35mmFilm; +@property SYMETADATA_PROPERTY_COPY NSNumber *sceneCaptureType; +@property SYMETADATA_PROPERTY_COPY NSNumber *gainControl; +@property SYMETADATA_PROPERTY_COPY NSNumber *contrast; +@property SYMETADATA_PROPERTY_COPY NSNumber *saturation; +@property SYMETADATA_PROPERTY_COPY NSNumber *sharpness; +@property SYMETADATA_PROPERTY_COPY NSObject *deviceSettingDescription; +@property SYMETADATA_PROPERTY_COPY NSNumber *subjectDistRange; +@property SYMETADATA_PROPERTY_COPY NSString *imageUniqueID; +@property SYMETADATA_PROPERTY_COPY NSString *cameraOwnerName; +@property SYMETADATA_PROPERTY_COPY NSString *bodySerialNumber; +@property SYMETADATA_PROPERTY_COPY NSArray *lensSpecification; +@property SYMETADATA_PROPERTY_COPY NSString *lensMake; +@property SYMETADATA_PROPERTY_COPY NSString *lensModel; +@property SYMETADATA_PROPERTY_COPY NSString *lensSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *gamma; +@property SYMETADATA_PROPERTY_COPY NSNumber *sensitivityType; +@property SYMETADATA_PROPERTY_COPY NSNumber *standardOutputSensitivity; +@property SYMETADATA_PROPERTY_COPY NSNumber *recommendedExposureIndex; +@property SYMETADATA_PROPERTY_COPY NSNumber *isoSpeed; +@property SYMETADATA_PROPERTY_COPY NSNumber *isoSpeedLatitudeyyy; +@property SYMETADATA_PROPERTY_COPY NSNumber *isoSpeedLatitudezzz; + +@end + + diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExif.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExif.m new file mode 100755 index 000000000..a5183a908 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExif.m @@ -0,0 +1,88 @@ +// +//SYMetadataEXIF.m +//SYPictureMetadataExample +// +//Created by Stan Chevallier on 12/13/12. +//Copyright (c2012 Syan. All rights reserved. +// + +#import "SYMetadataEXIF.h" +#import + +@implementation SYMetadataExif + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(exposureTime): (NSString *)kCGImagePropertyExifExposureTime, + SYStringSel(fNumber): (NSString *)kCGImagePropertyExifFNumber, + SYStringSel(exposureProgram): (NSString *)kCGImagePropertyExifExposureProgram, + SYStringSel(spectralSensitivity): (NSString *)kCGImagePropertyExifSpectralSensitivity, + SYStringSel(isoSpeedRatings): (NSString *)kCGImagePropertyExifISOSpeedRatings, + SYStringSel(oecf): (NSString *)kCGImagePropertyExifOECF, + SYStringSel(version): (NSString *)kCGImagePropertyExifVersion, + SYStringSel(dateTimeOriginal): (NSString *)kCGImagePropertyExifDateTimeOriginal, + SYStringSel(dateTimeDigitized): (NSString *)kCGImagePropertyExifDateTimeDigitized, + SYStringSel(componentsConfiguration): (NSString *)kCGImagePropertyExifComponentsConfiguration, + SYStringSel(compressedBitsPerPixel): (NSString *)kCGImagePropertyExifCompressedBitsPerPixel, + SYStringSel(shutterSpeedValue): (NSString *)kCGImagePropertyExifShutterSpeedValue, + SYStringSel(apertureValue): (NSString *)kCGImagePropertyExifApertureValue, + SYStringSel(brightnessValue): (NSString *)kCGImagePropertyExifBrightnessValue, + SYStringSel(exposureBiasValue): (NSString *)kCGImagePropertyExifExposureBiasValue, + SYStringSel(maxApertureValue): (NSString *)kCGImagePropertyExifMaxApertureValue, + SYStringSel(subjectDistance): (NSString *)kCGImagePropertyExifSubjectDistance, + SYStringSel(meteringMode): (NSString *)kCGImagePropertyExifMeteringMode, + SYStringSel(lightSource): (NSString *)kCGImagePropertyExifLightSource, + SYStringSel(flash): (NSString *)kCGImagePropertyExifFlash, + SYStringSel(focalLength): (NSString *)kCGImagePropertyExifFocalLength, + SYStringSel(subjectArea): (NSString *)kCGImagePropertyExifSubjectArea, + SYStringSel(makerNote): (NSString *)kCGImagePropertyExifMakerNote, + SYStringSel(userComment): (NSString *)kCGImagePropertyExifUserComment, + SYStringSel(subsecTime): (NSString *)kCGImagePropertyExifSubsecTime, + SYStringSel(subsecTimeOriginal): (NSString *)kCGImagePropertyExifSubsecTimeOrginal, + SYStringSel(subsecTimeDigitized): (NSString *)kCGImagePropertyExifSubsecTimeDigitized, + SYStringSel(flashPixVersion): (NSString *)kCGImagePropertyExifFlashPixVersion, + SYStringSel(colorSpace): (NSString *)kCGImagePropertyExifColorSpace, + SYStringSel(pixelXDimension): (NSString *)kCGImagePropertyExifPixelXDimension, + SYStringSel(pixelYDimension): (NSString *)kCGImagePropertyExifPixelYDimension, + SYStringSel(relatedSoundFile): (NSString *)kCGImagePropertyExifRelatedSoundFile, + SYStringSel(flashEnergy): (NSString *)kCGImagePropertyExifFlashEnergy, + SYStringSel(spatialFrequencyResponse): (NSString *)kCGImagePropertyExifSpatialFrequencyResponse, + SYStringSel(focalPlaneXResolution): (NSString *)kCGImagePropertyExifFocalPlaneXResolution, + SYStringSel(focalPlaneYResolution): (NSString *)kCGImagePropertyExifFocalPlaneYResolution, + SYStringSel(focalPlaneResolutionUnit): (NSString *)kCGImagePropertyExifFocalPlaneResolutionUnit, + SYStringSel(subjectLocation): (NSString *)kCGImagePropertyExifSubjectLocation, + SYStringSel(exposureIndex): (NSString *)kCGImagePropertyExifExposureIndex, + SYStringSel(sensingMethod): (NSString *)kCGImagePropertyExifSensingMethod, + SYStringSel(fileSource): (NSString *)kCGImagePropertyExifFileSource, + SYStringSel(sceneType): (NSString *)kCGImagePropertyExifSceneType, + SYStringSel(cfaPattern): (NSString *)kCGImagePropertyExifCFAPattern, + SYStringSel(customRendered): (NSString *)kCGImagePropertyExifCustomRendered, + SYStringSel(exposureMode): (NSString *)kCGImagePropertyExifExposureMode, + SYStringSel(whiteBalance): (NSString *)kCGImagePropertyExifWhiteBalance, + SYStringSel(digitalZoomRatio): (NSString *)kCGImagePropertyExifDigitalZoomRatio, + SYStringSel(focalLenIn35mmFilm): (NSString *)kCGImagePropertyExifFocalLenIn35mmFilm, + SYStringSel(sceneCaptureType): (NSString *)kCGImagePropertyExifSceneCaptureType, + SYStringSel(gainControl): (NSString *)kCGImagePropertyExifGainControl, + SYStringSel(contrast): (NSString *)kCGImagePropertyExifContrast, + SYStringSel(saturation): (NSString *)kCGImagePropertyExifSaturation, + SYStringSel(sharpness): (NSString *)kCGImagePropertyExifSharpness, + SYStringSel(deviceSettingDescription): (NSString *)kCGImagePropertyExifDeviceSettingDescription, + SYStringSel(subjectDistRange): (NSString *)kCGImagePropertyExifSubjectDistRange, + SYStringSel(imageUniqueID): (NSString *)kCGImagePropertyExifImageUniqueID, + SYStringSel(cameraOwnerName): (NSString *)kCGImagePropertyExifCameraOwnerName, + SYStringSel(bodySerialNumber): (NSString *)kCGImagePropertyExifBodySerialNumber, + SYStringSel(lensSpecification): (NSString *)kCGImagePropertyExifLensSpecification, + SYStringSel(lensMake): (NSString *)kCGImagePropertyExifLensMake, + SYStringSel(lensModel): (NSString *)kCGImagePropertyExifLensModel, + SYStringSel(lensSerialNumber): (NSString *)kCGImagePropertyExifLensSerialNumber, + SYStringSel(gamma): (NSString *)kCGImagePropertyExifGamma, + SYStringSel(sensitivityType): (NSString *)kCGImagePropertyExifSensitivityType, + SYStringSel(standardOutputSensitivity):(NSString *)kCGImagePropertyExifStandardOutputSensitivity, + SYStringSel(recommendedExposureIndex): (NSString *)kCGImagePropertyExifRecommendedExposureIndex, + SYStringSel(isoSpeed): (NSString *)kCGImagePropertyExifISOSpeed, + SYStringSel(isoSpeedLatitudeyyy): (NSString *)kCGImagePropertyExifISOSpeedLatitudeyyy, + SYStringSel(isoSpeedLatitudezzz): (NSString *)kCGImagePropertyExifISOSpeedLatitudezzz, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExifAux.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExifAux.h new file mode 100755 index 000000000..6335b69c6 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExifAux.h @@ -0,0 +1,27 @@ +// +// SYMetadataExifAux.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataExifAux : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSArray *lensInfo; +@property SYMETADATA_PROPERTY_COPY NSString *lensModel; +@property SYMETADATA_PROPERTY_COPY NSString *serialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *lensID; +@property SYMETADATA_PROPERTY_COPY NSString *lensSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *imageNumber; +@property SYMETADATA_PROPERTY_COPY NSObject *flashCompensation; +@property SYMETADATA_PROPERTY_COPY NSString *ownerName; +@property SYMETADATA_PROPERTY_COPY NSObject *firmware; +@property SYMETADATA_PROPERTY_COPY NSNumber *focusMode; +@property SYMETADATA_PROPERTY_COPY NSNumber *focusDistance; +@property SYMETADATA_PROPERTY_COPY NSArray *afInfo; +@property SYMETADATA_PROPERTY_COPY NSNumber *imageStabilization; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExifAux.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExifAux.m new file mode 100755 index 000000000..01d60d444 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataExifAux.m @@ -0,0 +1,35 @@ +// +// SYMetadataExifAux.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c 2012 Syan. All rights reserved. +// + +#import +#import "SYMetadataExifAux.h" + +@implementation SYMetadataExifAux + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(lensInfo): (NSString *)kCGImagePropertyExifAuxLensInfo, + SYStringSel(lensModel): (NSString *)kCGImagePropertyExifAuxLensModel, + SYStringSel(serialNumber): (NSString *)kCGImagePropertyExifAuxSerialNumber, + SYStringSel(lensID): (NSString *)kCGImagePropertyExifAuxLensID, + SYStringSel(lensSerialNumber): (NSString *)kCGImagePropertyExifAuxLensSerialNumber, + SYStringSel(imageNumber): (NSString *)kCGImagePropertyExifAuxImageNumber, + SYStringSel(flashCompensation): (NSString *)kCGImagePropertyExifAuxFlashCompensation, + SYStringSel(ownerName): (NSString *)kCGImagePropertyExifAuxOwnerName, + SYStringSel(firmware): (NSString *)kCGImagePropertyExifAuxFirmware, + + // iOS reads the data but the keys are not publicly declared, we use the Nikon equivalents + SYStringSel(focusMode): (NSString *)kCGImagePropertyMakerNikonFocusMode, + SYStringSel(focusDistance): (NSString *)kCGImagePropertyMakerNikonFocusDistance, + + SYStringSel(afInfo): (NSString *)kSYImagePropertyExifAuxAutoFocusInfo, + SYStringSel(imageStabilization): (NSString *)kSYImagePropertyExifAuxImageStabilization, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGIF.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGIF.h new file mode 100755 index 000000000..0b56e05f8 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGIF.h @@ -0,0 +1,19 @@ +// +// SYMetadataGIF.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataGIF : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSNumber *loopCount; +@property SYMETADATA_PROPERTY_COPY NSNumber *delayTime; +@property SYMETADATA_PROPERTY_COPY NSArray *imageColorMap; +@property SYMETADATA_PROPERTY_COPY NSNumber *hasGlobalColorMap; +@property SYMETADATA_PROPERTY_COPY NSNumber *unclampedDelayTime; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGIF.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGIF.m new file mode 100755 index 000000000..7a99676b4 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGIF.m @@ -0,0 +1,24 @@ +// +// SYMetadataGIF.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataGIF.h" +#import + +@implementation SYMetadataGIF + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(loopCount): (NSString *)kCGImagePropertyGIFLoopCount, + SYStringSel(delayTime): (NSString *)kCGImagePropertyGIFDelayTime, + SYStringSel(imageColorMap): (NSString *)kCGImagePropertyGIFImageColorMap, + SYStringSel(hasGlobalColorMap): (NSString *)kCGImagePropertyGIFHasGlobalColorMap, + SYStringSel(unclampedDelayTime): (NSString *)kCGImagePropertyGIFUnclampedDelayTime, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGPS.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGPS.h new file mode 100755 index 000000000..928ac8ff3 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGPS.h @@ -0,0 +1,48 @@ +// +// SYMetadataGPS.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +// TODO: use enum for refs instead of strings + +@interface SYMetadataGPS : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSArray *version; +@property SYMETADATA_PROPERTY_COPY NSString *latitudeRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *latitude; +@property SYMETADATA_PROPERTY_COPY NSString *longitudeRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *longitude; +@property SYMETADATA_PROPERTY_COPY NSNumber *altitudeRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *altitude; +@property SYMETADATA_PROPERTY_COPY NSString *timeStamp; +@property SYMETADATA_PROPERTY_COPY NSString *satellites; +@property SYMETADATA_PROPERTY_COPY NSString *status; +@property SYMETADATA_PROPERTY_COPY NSString *measureMode; +@property SYMETADATA_PROPERTY_COPY NSNumber *dop; +@property SYMETADATA_PROPERTY_COPY NSString *speedRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *speed; +@property SYMETADATA_PROPERTY_COPY NSString *trackRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *track; +@property SYMETADATA_PROPERTY_COPY NSString *imgDirectionRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *imgDirection; +@property SYMETADATA_PROPERTY_COPY NSString *mapDatum; +@property SYMETADATA_PROPERTY_COPY NSString *destLatitudeRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *destLatitude; +@property SYMETADATA_PROPERTY_COPY NSString *destLongitudeRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *destLongitude; +@property SYMETADATA_PROPERTY_COPY NSString *destBearingRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *destBearing; +@property SYMETADATA_PROPERTY_COPY NSString *destDistanceRef; +@property SYMETADATA_PROPERTY_COPY NSNumber *destDistance; +@property SYMETADATA_PROPERTY_COPY NSString *processingMethod; +@property SYMETADATA_PROPERTY_COPY NSObject *areaInformation; +@property SYMETADATA_PROPERTY_COPY NSString *dateStamp; +@property SYMETADATA_PROPERTY_COPY NSNumber *differental; +@property SYMETADATA_PROPERTY_COPY NSNumber *hPositioningError; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGPS.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGPS.m new file mode 100755 index 000000000..5f4b6e82f --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataGPS.m @@ -0,0 +1,51 @@ +// +// SYMetadataGPS.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataGPS.h" +#import + +@implementation SYMetadataGPS + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(version): (NSString *)kCGImagePropertyGPSVersion, + SYStringSel(latitudeRef): (NSString *)kCGImagePropertyGPSLatitudeRef, + SYStringSel(latitude): (NSString *)kCGImagePropertyGPSLatitude, + SYStringSel(longitudeRef): (NSString *)kCGImagePropertyGPSLongitudeRef, + SYStringSel(longitude): (NSString *)kCGImagePropertyGPSLongitude, + SYStringSel(altitudeRef): (NSString *)kCGImagePropertyGPSAltitudeRef, + SYStringSel(altitude): (NSString *)kCGImagePropertyGPSAltitude, + SYStringSel(timeStamp): (NSString *)kCGImagePropertyGPSTimeStamp, + SYStringSel(satellites): (NSString *)kCGImagePropertyGPSSatellites, + SYStringSel(status): (NSString *)kCGImagePropertyGPSStatus, + SYStringSel(measureMode): (NSString *)kCGImagePropertyGPSMeasureMode, + SYStringSel(dop): (NSString *)kCGImagePropertyGPSDOP, + SYStringSel(speedRef): (NSString *)kCGImagePropertyGPSSpeedRef, + SYStringSel(speed): (NSString *)kCGImagePropertyGPSSpeed, + SYStringSel(trackRef): (NSString *)kCGImagePropertyGPSTrackRef, + SYStringSel(track): (NSString *)kCGImagePropertyGPSTrack, + SYStringSel(imgDirectionRef): (NSString *)kCGImagePropertyGPSImgDirectionRef, + SYStringSel(imgDirection): (NSString *)kCGImagePropertyGPSImgDirection, + SYStringSel(mapDatum): (NSString *)kCGImagePropertyGPSMapDatum, + SYStringSel(destLatitudeRef): (NSString *)kCGImagePropertyGPSDestLatitudeRef, + SYStringSel(destLatitude): (NSString *)kCGImagePropertyGPSDestLatitude, + SYStringSel(destLongitudeRef): (NSString *)kCGImagePropertyGPSDestLongitudeRef, + SYStringSel(destLongitude): (NSString *)kCGImagePropertyGPSDestLongitude, + SYStringSel(destBearingRef): (NSString *)kCGImagePropertyGPSDestBearingRef, + SYStringSel(destBearing): (NSString *)kCGImagePropertyGPSDestBearing, + SYStringSel(destDistanceRef): (NSString *)kCGImagePropertyGPSDestDistanceRef, + SYStringSel(destDistance): (NSString *)kCGImagePropertyGPSDestDistance, + SYStringSel(processingMethod): (NSString *)kCGImagePropertyGPSProcessingMethod, + SYStringSel(areaInformation): (NSString *)kCGImagePropertyGPSAreaInformation, + SYStringSel(dateStamp): (NSString *)kCGImagePropertyGPSDateStamp, + SYStringSel(differental): (NSString *)kCGImagePropertyGPSDifferental, + SYStringSel(hPositioningError):(NSString *)kCGImagePropertyGPSHPositioningError, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTC.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTC.h new file mode 100755 index 000000000..f2c1d864e --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTC.h @@ -0,0 +1,66 @@ +// +// SYMetadataIPTC.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" +#import "SYMetadataIPTCContactInfo.h" + +@interface SYMetadataIPTC : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSString *objectTypeReference; +@property SYMETADATA_PROPERTY_COPY NSArray *objectAttributeReference; +@property SYMETADATA_PROPERTY_COPY NSString *objectName; +@property SYMETADATA_PROPERTY_COPY NSString *editStatus; +@property SYMETADATA_PROPERTY_COPY NSString *editorialUpdate; +@property SYMETADATA_PROPERTY_COPY NSString *urgency; +@property SYMETADATA_PROPERTY_COPY NSArray *subjectReference; +@property SYMETADATA_PROPERTY_COPY NSString *category; +@property SYMETADATA_PROPERTY_COPY NSArray *supplementalCategory; +@property SYMETADATA_PROPERTY_COPY NSString *fixtureIdentifier; +@property SYMETADATA_PROPERTY_COPY NSArray *keywords; +@property SYMETADATA_PROPERTY_COPY NSArray *contentLocationCode; +@property SYMETADATA_PROPERTY_COPY NSArray *contentLocationName; +@property SYMETADATA_PROPERTY_COPY NSString *releaseDate; +@property SYMETADATA_PROPERTY_COPY NSString *releaseTime; +@property SYMETADATA_PROPERTY_COPY NSString *expirationDate; +@property SYMETADATA_PROPERTY_COPY NSString *expirationTime; +@property SYMETADATA_PROPERTY_COPY NSString *specialInstructions; +@property SYMETADATA_PROPERTY_COPY NSString *actionAdvised; +@property SYMETADATA_PROPERTY_COPY NSArray *referenceService; +@property SYMETADATA_PROPERTY_COPY NSArray *referenceDate; +@property SYMETADATA_PROPERTY_COPY NSArray *referenceNumber; +@property SYMETADATA_PROPERTY_COPY NSString *dateCreated; +@property SYMETADATA_PROPERTY_COPY NSString *timeCreated; +@property SYMETADATA_PROPERTY_COPY NSString *digitalCreationDate; +@property SYMETADATA_PROPERTY_COPY NSString *digitalCreationTime; +@property SYMETADATA_PROPERTY_COPY NSString *originatingProgram; +@property SYMETADATA_PROPERTY_COPY NSString *programVersion; +@property SYMETADATA_PROPERTY_COPY NSString *objectCycle; +@property SYMETADATA_PROPERTY_COPY NSArray *byline; +@property SYMETADATA_PROPERTY_COPY NSArray *bylineTitle; +@property SYMETADATA_PROPERTY_COPY NSString *city; +@property SYMETADATA_PROPERTY_COPY NSString *subLocation; +@property SYMETADATA_PROPERTY_COPY NSString *provinceState; +@property SYMETADATA_PROPERTY_COPY NSString *countryPrimaryLocationCode; +@property SYMETADATA_PROPERTY_COPY NSString *countryPrimaryLocationName; +@property SYMETADATA_PROPERTY_COPY NSString *originalTransmissionReference; +@property SYMETADATA_PROPERTY_COPY NSString *headline; +@property SYMETADATA_PROPERTY_COPY NSString *credit; +@property SYMETADATA_PROPERTY_COPY NSString *source; +@property SYMETADATA_PROPERTY_COPY NSString *copyrightNotice; +@property SYMETADATA_PROPERTY_COPY NSArray *contact; +@property SYMETADATA_PROPERTY_COPY NSString *captionAbstract; +@property SYMETADATA_PROPERTY_COPY NSArray *writerEditor; +@property SYMETADATA_PROPERTY_COPY NSString *imageType; +@property SYMETADATA_PROPERTY_COPY NSString *imageOrientation; +@property SYMETADATA_PROPERTY_COPY NSString *languageIdentifier; +@property SYMETADATA_PROPERTY_COPY NSNumber *starRating; +@property SYMETADATA_PROPERTY_COPY SYMetadataIPTCContactInfo *creatorContactInfo; +@property SYMETADATA_PROPERTY_COPY NSString *rightsUsageTerms; +@property SYMETADATA_PROPERTY_COPY NSString *scene; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTC.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTC.m new file mode 100755 index 000000000..952b29c6d --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTC.m @@ -0,0 +1,80 @@ +// +// SYMetadataIPTC.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataIPTC.h" +#import + +@implementation SYMetadataIPTC + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(objectTypeReference): (NSString *)kCGImagePropertyIPTCObjectTypeReference, + SYStringSel(objectAttributeReference): (NSString *)kCGImagePropertyIPTCObjectAttributeReference, + SYStringSel(objectName): (NSString *)kCGImagePropertyIPTCObjectName, + SYStringSel(editStatus): (NSString *)kCGImagePropertyIPTCEditStatus, + SYStringSel(editorialUpdate): (NSString *)kCGImagePropertyIPTCEditorialUpdate, + SYStringSel(urgency): (NSString *)kCGImagePropertyIPTCUrgency, + SYStringSel(subjectReference): (NSString *)kCGImagePropertyIPTCSubjectReference, + SYStringSel(category): (NSString *)kCGImagePropertyIPTCCategory, + SYStringSel(supplementalCategory): (NSString *)kCGImagePropertyIPTCSupplementalCategory, + SYStringSel(fixtureIdentifier): (NSString *)kCGImagePropertyIPTCFixtureIdentifier, + SYStringSel(keywords): (NSString *)kCGImagePropertyIPTCKeywords, + SYStringSel(contentLocationCode): (NSString *)kCGImagePropertyIPTCContentLocationCode, + SYStringSel(contentLocationName): (NSString *)kCGImagePropertyIPTCContentLocationName, + SYStringSel(releaseDate): (NSString *)kCGImagePropertyIPTCReleaseDate, + SYStringSel(releaseTime): (NSString *)kCGImagePropertyIPTCReleaseTime, + SYStringSel(expirationDate): (NSString *)kCGImagePropertyIPTCExpirationDate, + SYStringSel(expirationTime): (NSString *)kCGImagePropertyIPTCExpirationTime, + SYStringSel(specialInstructions): (NSString *)kCGImagePropertyIPTCSpecialInstructions, + SYStringSel(actionAdvised): (NSString *)kCGImagePropertyIPTCActionAdvised, + SYStringSel(referenceService): (NSString *)kCGImagePropertyIPTCReferenceService, + SYStringSel(referenceDate): (NSString *)kCGImagePropertyIPTCReferenceDate, + SYStringSel(referenceNumber): (NSString *)kCGImagePropertyIPTCReferenceNumber, + SYStringSel(dateCreated): (NSString *)kCGImagePropertyIPTCDateCreated, + SYStringSel(timeCreated): (NSString *)kCGImagePropertyIPTCTimeCreated, + SYStringSel(digitalCreationDate): (NSString *)kCGImagePropertyIPTCDigitalCreationDate, + SYStringSel(digitalCreationTime): (NSString *)kCGImagePropertyIPTCDigitalCreationTime, + SYStringSel(originatingProgram): (NSString *)kCGImagePropertyIPTCOriginatingProgram, + SYStringSel(programVersion): (NSString *)kCGImagePropertyIPTCProgramVersion, + SYStringSel(objectCycle): (NSString *)kCGImagePropertyIPTCObjectCycle, + SYStringSel(byline): (NSString *)kCGImagePropertyIPTCByline, + SYStringSel(bylineTitle): (NSString *)kCGImagePropertyIPTCBylineTitle, + SYStringSel(city): (NSString *)kCGImagePropertyIPTCCity, + SYStringSel(subLocation): (NSString *)kCGImagePropertyIPTCSubLocation, + SYStringSel(provinceState): (NSString *)kCGImagePropertyIPTCProvinceState, + SYStringSel(countryPrimaryLocationCode): (NSString *)kCGImagePropertyIPTCCountryPrimaryLocationCode, + SYStringSel(countryPrimaryLocationName): (NSString *)kCGImagePropertyIPTCCountryPrimaryLocationName, + SYStringSel(originalTransmissionReference): (NSString *)kCGImagePropertyIPTCOriginalTransmissionReference, + SYStringSel(headline): (NSString *)kCGImagePropertyIPTCHeadline, + SYStringSel(credit): (NSString *)kCGImagePropertyIPTCCredit, + SYStringSel(source): (NSString *)kCGImagePropertyIPTCSource, + SYStringSel(copyrightNotice): (NSString *)kCGImagePropertyIPTCCopyrightNotice, + SYStringSel(contact): (NSString *)kCGImagePropertyIPTCContact, + SYStringSel(captionAbstract): (NSString *)kCGImagePropertyIPTCCaptionAbstract, + SYStringSel(writerEditor): (NSString *)kCGImagePropertyIPTCWriterEditor, + SYStringSel(imageType): (NSString *)kCGImagePropertyIPTCImageType, + SYStringSel(imageOrientation): (NSString *)kCGImagePropertyIPTCImageOrientation, + SYStringSel(languageIdentifier): (NSString *)kCGImagePropertyIPTCLanguageIdentifier, + SYStringSel(starRating): (NSString *)kCGImagePropertyIPTCStarRating, + SYStringSel(creatorContactInfo): (NSString *)kCGImagePropertyIPTCCreatorContactInfo, + SYStringSel(rightsUsageTerms): (NSString *)kCGImagePropertyIPTCRightsUsageTerms, + SYStringSel(scene): (NSString *)kCGImagePropertyIPTCScene, + }; +} + ++ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key +{ + if ([key isEqualToString:SYStringSel(creatorContactInfo)]) + { + return [NSValueTransformer sy_dictionaryTransformerForModelOfClass:[SYMetadataIPTCContactInfo class]]; + } + + return [super JSONTransformerForKey:key]; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTCContactInfo.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTCContactInfo.h new file mode 100755 index 000000000..67838898b --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTCContactInfo.h @@ -0,0 +1,22 @@ +// +// SYMetadataIPTCContactInfo.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataIPTCContactInfo : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSString *city; +@property SYMETADATA_PROPERTY_COPY NSString *country; +@property SYMETADATA_PROPERTY_COPY NSString *address; +@property SYMETADATA_PROPERTY_COPY NSString *postalCode; +@property SYMETADATA_PROPERTY_COPY NSString *stateProvince; +@property SYMETADATA_PROPERTY_COPY NSString *emails; +@property SYMETADATA_PROPERTY_COPY NSString *phones; +@property SYMETADATA_PROPERTY_COPY NSString *webURLs; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTCContactInfo.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTCContactInfo.m new file mode 100755 index 000000000..4ba9852a4 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataIPTCContactInfo.m @@ -0,0 +1,27 @@ +// +// SYMetadataIPTCContactInfo.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataIPTCContactInfo.h" +#import + +@implementation SYMetadataIPTCContactInfo + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(city): (NSString *)kCGImagePropertyIPTCContactInfoCity, + SYStringSel(country): (NSString *)kCGImagePropertyIPTCContactInfoCountry, + SYStringSel(address): (NSString *)kCGImagePropertyIPTCContactInfoAddress, + SYStringSel(postalCode): (NSString *)kCGImagePropertyIPTCContactInfoPostalCode, + SYStringSel(stateProvince):(NSString *)kCGImagePropertyIPTCContactInfoStateProvince, + SYStringSel(emails): (NSString *)kCGImagePropertyIPTCContactInfoEmails, + SYStringSel(phones): (NSString *)kCGImagePropertyIPTCContactInfoPhones, + SYStringSel(webURLs): (NSString *)kCGImagePropertyIPTCContactInfoWebURLs, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataJFIF.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataJFIF.h new file mode 100755 index 000000000..23dd83c54 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataJFIF.h @@ -0,0 +1,19 @@ +// +// SYMetadataJFIF.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataJFIF : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSArray *version; +@property SYMETADATA_PROPERTY_COPY NSNumber *xDensity; +@property SYMETADATA_PROPERTY_COPY NSNumber *yDensity; +@property SYMETADATA_PROPERTY_COPY NSNumber *densityUnit; +@property SYMETADATA_PROPERTY_COPY NSNumber *isProgressive; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataJFIF.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataJFIF.m new file mode 100755 index 000000000..9c68fc468 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataJFIF.m @@ -0,0 +1,24 @@ +// +// SYMetadataJFIF.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataJFIF.h" +#import + +@implementation SYMetadataJFIF + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(version): (NSString *)kCGImagePropertyJFIFVersion, + SYStringSel(xDensity): (NSString *)kCGImagePropertyJFIFXDensity, + SYStringSel(yDensity): (NSString *)kCGImagePropertyJFIFYDensity, + SYStringSel(densityUnit): (NSString *)kCGImagePropertyJFIFDensityUnit, + SYStringSel(isProgressive):(NSString *)kCGImagePropertyJFIFIsProgressive, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerCanon.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerCanon.h new file mode 100755 index 000000000..39b1c23fd --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerCanon.h @@ -0,0 +1,38 @@ +// +// SYMetadataMakerCanon.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +typedef enum : NSUInteger { + SYMetadataMakerCanonContinuousDriver_Single = 0, + SYMetadataMakerCanonContinuousDriver_Continuous = 1, + SYMetadataMakerCanonContinuousDriver_Movie = 2, + SYMetadataMakerCanonContinuousDriver_ContinuousSpeedPriority = 3, + SYMetadataMakerCanonContinuousDriver_ContinuousLow = 4, + SYMetadataMakerCanonContinuousDriver_ContinuousHigh = 5, + SYMetadataMakerCanonContinuousDriver_SilentSingle = 6, + SYMetadataMakerCanonContinuousDriver_SingleSilent = 9, + SYMetadataMakerCanonContinuousDriver_ContinuousSilent = 10, +} SYMetadataMakerCanonContinuousDriver; + +@interface SYMetadataMakerCanon : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSString *ownerName; +@property SYMETADATA_PROPERTY_COPY NSNumber *cameraSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *imageSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *flashExposureComp; +@property SYMETADATA_PROPERTY_COPY NSNumber *continuousDrive; +@property SYMETADATA_PROPERTY_COPY NSString *lensModel; +@property SYMETADATA_PROPERTY_COPY NSString *firmware; +@property SYMETADATA_PROPERTY_COPY NSNumber *aspectRatioInfo; +@property SYMETADATA_PROPERTY_COPY NSNumber *whiteBalanceIndex; +@property SYMETADATA_PROPERTY_COPY NSNumber *uniqueModelID; +@property SYMETADATA_PROPERTY_COPY NSNumber *maxAperture; +@property SYMETADATA_PROPERTY_COPY NSNumber *minAperture; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerCanon.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerCanon.m new file mode 100755 index 000000000..c9b162765 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerCanon.m @@ -0,0 +1,35 @@ +// +// SYMetadataMakerCanon.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataMakerCanon.h" +#import + +@implementation SYMetadataMakerCanon + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(ownerName): (NSString *)kCGImagePropertyMakerCanonOwnerName, + SYStringSel(cameraSerialNumber): (NSString *)kCGImagePropertyMakerCanonCameraSerialNumber, + SYStringSel(imageSerialNumber): (NSString *)kCGImagePropertyMakerCanonImageSerialNumber, + SYStringSel(flashExposureComp): (NSString *)kCGImagePropertyMakerCanonFlashExposureComp, + SYStringSel(continuousDrive): (NSString *)kCGImagePropertyMakerCanonContinuousDrive, + SYStringSel(lensModel): (NSString *)kCGImagePropertyMakerCanonLensModel, + SYStringSel(firmware): (NSString *)kCGImagePropertyMakerCanonFirmware, + SYStringSel(aspectRatioInfo): (NSString *)kCGImagePropertyMakerCanonAspectRatioInfo, + + // data is read by iOS but is not accessible via a publicly declared key. we use the one from CIFF + SYStringSel(whiteBalanceIndex): (NSString *)kCGImagePropertyCIFFWhiteBalanceIndex, + + SYStringSel(maxAperture): (NSString *)kSYImagePropertyCIFFMaxAperture, + SYStringSel(minAperture): (NSString *)kSYImagePropertyCIFFMinAperture, + SYStringSel(uniqueModelID): (NSString *)kSYImagePropertyCIFFUniqueModelID, + }; +} + +@end + diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerFuji.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerFuji.h new file mode 100755 index 000000000..001b732b8 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerFuji.h @@ -0,0 +1,13 @@ +// +// SYMetadataMakerFuji.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataMakerFuji : SYMetadataBase + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerFuji.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerFuji.m new file mode 100755 index 000000000..101f2f10d --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerFuji.m @@ -0,0 +1,13 @@ +// +// SYMetadataMakerFuji.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataMakerFuji.h" + +@implementation SYMetadataMakerFuji + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerMinolta.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerMinolta.h new file mode 100755 index 000000000..3301a31bf --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerMinolta.h @@ -0,0 +1,13 @@ +// +// SYMetadataMakerMinolta.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataMakerMinolta : SYMetadataBase + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerMinolta.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerMinolta.m new file mode 100755 index 000000000..f9030b12e --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerMinolta.m @@ -0,0 +1,13 @@ +// +// SYMetadataMakerMinolta.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataMakerMinolta.h" + +@implementation SYMetadataMakerMinolta + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerNikon.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerNikon.h new file mode 100755 index 000000000..b4696b3f1 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerNikon.h @@ -0,0 +1,51 @@ +// +// SYMetadataMakerNikon.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +typedef enum : NSUInteger { + SYMetadataMakerNikonShootingMode_Continuous = 1 << 0L, + SYMetadataMakerNikonShootingMode_Delay = 1 << 1L, + SYMetadataMakerNikonShootingMode_PCControl = 1 << 2L, + SYMetadataMakerNikonShootingMode_Selftimer = 1 << 3L, + SYMetadataMakerNikonShootingMode_ExposureBracketing = 1 << 4L, + SYMetadataMakerNikonShootingMode_AutoISO = 1 << 5L, + SYMetadataMakerNikonShootingMode_WhiteBalanceBracketing = 1 << 6L, + SYMetadataMakerNikonShootingMode_IRControl = 1 << 7L, + SYMetadataMakerNikonShootingMode_DLightingBracketing = 1 << 8L, +} SYMetadataMakerNikonShootingMode; + +typedef enum : NSUInteger { + SYMetadataMakerNikonLensType_MF = 1 << 0L, + SYMetadataMakerNikonLensType_D = 1 << 1L, + SYMetadataMakerNikonLensType_G = 1 << 2L, + SYMetadataMakerNikonLensType_VR = 1 << 3L, +} SYMetadataMakerNikonLensType; + +@interface SYMetadataMakerNikon : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSArray *isoSetting; +@property SYMETADATA_PROPERTY_COPY NSString *colorMode; +@property SYMETADATA_PROPERTY_COPY NSString *quality; +@property SYMETADATA_PROPERTY_COPY NSString *whiteBalanceMode; +@property SYMETADATA_PROPERTY_COPY NSString *sharpenMode; +@property SYMETADATA_PROPERTY_COPY NSString *focusMode; +@property SYMETADATA_PROPERTY_COPY NSString *flashSetting; +@property SYMETADATA_PROPERTY_COPY NSString *isoSelection; +@property SYMETADATA_PROPERTY_COPY NSObject *flashExposureComp; +@property SYMETADATA_PROPERTY_COPY NSString *imageAdjustment; +@property SYMETADATA_PROPERTY_COPY NSObject *lensAdapter; +@property SYMETADATA_PROPERTY_COPY NSNumber *lensType; +@property SYMETADATA_PROPERTY_COPY NSObject *lensInfo; +@property SYMETADATA_PROPERTY_COPY NSNumber *focusDistance; +@property SYMETADATA_PROPERTY_COPY NSNumber *digitalZoom; +@property SYMETADATA_PROPERTY_COPY NSNumber *shootingMode; +@property SYMETADATA_PROPERTY_COPY NSString *cameraSerialNumber; +@property SYMETADATA_PROPERTY_COPY NSNumber *shutterCount; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerNikon.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerNikon.m new file mode 100755 index 000000000..f27c4b3df --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerNikon.m @@ -0,0 +1,37 @@ +// +// SYMetadataMakerNikon.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataMakerNikon.h" +#import + +@implementation SYMetadataMakerNikon + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(isoSetting): (NSString *)kCGImagePropertyMakerNikonISOSetting, + SYStringSel(colorMode): (NSString *)kCGImagePropertyMakerNikonColorMode, + SYStringSel(quality): (NSString *)kCGImagePropertyMakerNikonQuality, + SYStringSel(whiteBalanceMode): (NSString *)kCGImagePropertyMakerNikonWhiteBalanceMode, + SYStringSel(sharpenMode): (NSString *)kCGImagePropertyMakerNikonSharpenMode, + SYStringSel(focusMode): (NSString *)kCGImagePropertyMakerNikonFocusMode, + SYStringSel(flashSetting): (NSString *)kCGImagePropertyMakerNikonFlashSetting, + SYStringSel(isoSelection): (NSString *)kCGImagePropertyMakerNikonISOSelection, + SYStringSel(flashExposureComp): (NSString *)kCGImagePropertyMakerNikonFlashExposureComp, + SYStringSel(imageAdjustment): (NSString *)kCGImagePropertyMakerNikonImageAdjustment, + SYStringSel(lensAdapter): (NSString *)kCGImagePropertyMakerNikonLensAdapter, + SYStringSel(lensType): (NSString *)kCGImagePropertyMakerNikonLensType, + SYStringSel(lensInfo): (NSString *)kCGImagePropertyMakerNikonLensInfo, + SYStringSel(focusDistance): (NSString *)kCGImagePropertyMakerNikonFocusDistance, + SYStringSel(digitalZoom): (NSString *)kCGImagePropertyMakerNikonDigitalZoom, + SYStringSel(shootingMode): (NSString *)kCGImagePropertyMakerNikonShootingMode, + SYStringSel(cameraSerialNumber): (NSString *)kCGImagePropertyMakerNikonCameraSerialNumber, + SYStringSel(shutterCount): (NSString *)kCGImagePropertyMakerNikonShutterCount, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerOlympus.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerOlympus.h new file mode 100755 index 000000000..a1b81b4fa --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerOlympus.h @@ -0,0 +1,13 @@ +// +// SYMetadataMakerOlympus.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataMakerOlympus : SYMetadataBase + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerOlympus.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerOlympus.m new file mode 100755 index 000000000..cf18ce2e0 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerOlympus.m @@ -0,0 +1,13 @@ +// +// SYMetadataMakerOlympus.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataMakerOlympus.h" + +@implementation SYMetadataMakerOlympus + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerPentax.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerPentax.h new file mode 100755 index 000000000..99bdf6c8c --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerPentax.h @@ -0,0 +1,13 @@ +// +// SYMetadataMakerPentax.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataMakerPentax : SYMetadataBase + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerPentax.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerPentax.m new file mode 100755 index 000000000..d707d036e --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataMakerPentax.m @@ -0,0 +1,13 @@ +// +// SYMetadataMakerPentax.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataMakerPentax.h" + +@implementation SYMetadataMakerPentax + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataPNG.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataPNG.h new file mode 100755 index 000000000..6e78bd3d9 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataPNG.h @@ -0,0 +1,51 @@ +// +// SYMetadataPNG.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" +#import + +typedef enum : NSUInteger { + SYMetadataPNGsRGBIntent_Perceptual = 0, + SYMetadataPNGsRGBIntent_RelativeColorimetric = 1, + SYMetadataPNGsRGBIntent_Saturation = 2, + SYMetadataPNGsRGBIntent_AbsoluteColorimetric = 3, +} SYMetadataPNGsRGBIntent; + + +typedef enum : NSUInteger { + SYMetadataPNGCompressionFilter_NoFilters = IMAGEIO_PNG_NO_FILTERS, + SYMetadataPNGCompressionFilter_None = IMAGEIO_PNG_FILTER_NONE, + SYMetadataPNGCompressionFilter_Sub = IMAGEIO_PNG_FILTER_SUB, + SYMetadataPNGCompressionFilter_Up = IMAGEIO_PNG_FILTER_UP, + SYMetadataPNGCompressionFilter_Avg = IMAGEIO_PNG_FILTER_AVG, + SYMetadataPNGCompressionFilter_Paeth = IMAGEIO_PNG_FILTER_PAETH, + SYMetadataPNGCompressionFilter_All = IMAGEIO_PNG_ALL_FILTERS, +} SYMetadataPNGCompressionFilter; + + +@interface SYMetadataPNG : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSNumber *gamma; +@property SYMETADATA_PROPERTY_COPY NSNumber *interlaceType; +@property SYMETADATA_PROPERTY_COPY NSNumber *xPixelsPerMeter; +@property SYMETADATA_PROPERTY_COPY NSNumber *yPixelsPerMeter; +@property SYMETADATA_PROPERTY_COPY NSNumber *sRGBIntent; +@property SYMETADATA_PROPERTY_COPY NSArray *chromaticities; +@property SYMETADATA_PROPERTY_COPY NSString *author; +@property SYMETADATA_PROPERTY_COPY NSString *copyright; +@property SYMETADATA_PROPERTY_COPY NSString *creationTime; +@property SYMETADATA_PROPERTY_COPY NSString *descr; +@property SYMETADATA_PROPERTY_COPY NSString *modificationTime; +@property SYMETADATA_PROPERTY_COPY NSString *software; +@property SYMETADATA_PROPERTY_COPY NSString *title; +@property SYMETADATA_PROPERTY_COPY NSNumber *loopCount; +@property SYMETADATA_PROPERTY_COPY NSNumber *delayTime; +@property SYMETADATA_PROPERTY_COPY NSNumber *unclampedDelayTime; +@property SYMETADATA_PROPERTY_COPY NSNumber *compressionFilter; + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataPNG.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataPNG.m new file mode 100755 index 000000000..41927e187 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataPNG.m @@ -0,0 +1,36 @@ +// +// SYMetadataPNG.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataPNG.h" +#import + +@implementation SYMetadataPNG + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(gamma): (NSString *)kCGImagePropertyPNGGamma, + SYStringSel(interlaceType): (NSString *)kCGImagePropertyPNGInterlaceType, + SYStringSel(xPixelsPerMeter): (NSString *)kCGImagePropertyPNGXPixelsPerMeter, + SYStringSel(yPixelsPerMeter): (NSString *)kCGImagePropertyPNGYPixelsPerMeter, + SYStringSel(sRGBIntent): (NSString *)kCGImagePropertyPNGsRGBIntent, + SYStringSel(chromaticities): (NSString *)kCGImagePropertyPNGChromaticities, + SYStringSel(author): (NSString *)kCGImagePropertyPNGAuthor, + SYStringSel(copyright): (NSString *)kCGImagePropertyPNGCopyright, + SYStringSel(creationTime): (NSString *)kCGImagePropertyPNGCreationTime, + SYStringSel(descr): (NSString *)kCGImagePropertyPNGDescription, + SYStringSel(modificationTime): (NSString *)kCGImagePropertyPNGModificationTime, + SYStringSel(software): (NSString *)kCGImagePropertyPNGSoftware, + SYStringSel(title): (NSString *)kCGImagePropertyPNGTitle, + SYStringSel(loopCount): (NSString *)kCGImagePropertyAPNGLoopCount, + SYStringSel(delayTime): (NSString *)kCGImagePropertyAPNGDelayTime, + SYStringSel(unclampedDelayTime): (NSString *)kCGImagePropertyAPNGUnclampedDelayTime, + SYStringSel(compressionFilter): (NSString *)kCGImagePropertyPNGCompressionFilter, + }; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataRaw.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataRaw.h new file mode 100755 index 000000000..6dfb5978f --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataRaw.h @@ -0,0 +1,13 @@ +// +// SYMetadataRaw.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataBase.h" + +@interface SYMetadataRaw : SYMetadataBase + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataRaw.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataRaw.m new file mode 100755 index 000000000..51f3a1b4f --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataRaw.m @@ -0,0 +1,13 @@ +// +// SYMetadataRaw.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/16/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataRaw.h" + +@implementation SYMetadataRaw + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataTIFF.h b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataTIFF.h new file mode 100755 index 000000000..092e59c24 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataTIFF.h @@ -0,0 +1,66 @@ +// +// SYMetadataTIFF.h +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/13/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import +#import "SYMetadataBase.h" + +typedef enum { + SYPictureTiffOrientation_Unknown = 0, + SYPictureTiffOrientation_TopLeft = 1, + SYPictureTiffOrientation_TopRight = 2, + SYPictureTiffOrientation_BottomRight = 3, + SYPictureTiffOrientation_BottomLeft = 4, + SYPictureTiffOrientation_LeftTop = 5, + SYPictureTiffOrientation_RightTop = 6, + SYPictureTiffOrientation_RightBottom = 7, + SYPictureTiffOrientation_LeftBottom = 8, +} SYPictureTiffOrientation; + + +typedef enum { + SYPictureTiffPhotometricInterpretation_MINISWHITE = 0, + SYPictureTiffPhotometricInterpretation_MINISBLACK = 1, + SYPictureTiffPhotometricInterpretation_RGB = 2, + SYPictureTiffPhotometricInterpretation_PALETTE = 3, + SYPictureTiffPhotometricInterpretation_MASK = 4, + SYPictureTiffPhotometricInterpretation_SEPARATED = 5, + SYPictureTiffPhotometricInterpretation_YCBCR = 6, + SYPictureTiffPhotometricInterpretation_CIELAB = 8, + SYPictureTiffPhotometricInterpretation_ICCLAB = 9, + SYPictureTiffPhotometricInterpretation_ITULAB = 10, + SYPictureTiffPhotometricInterpretation_LOGL = 32844, + SYPictureTiffPhotometricInterpretation_LOGLUV = 32845, +} SYPictureTiffPhotometricInterpretation; + + + +@interface SYMetadataTIFF : SYMetadataBase + +@property SYMETADATA_PROPERTY_COPY NSNumber *compression; +@property SYMETADATA_PROPERTY_COPY NSNumber *photometricInterpretation; +@property SYMETADATA_PROPERTY_COPY NSString *documentName; +@property SYMETADATA_PROPERTY_COPY NSString *imageDescription; +@property SYMETADATA_PROPERTY_COPY NSString *make; +@property SYMETADATA_PROPERTY_COPY NSString *model; +@property SYMETADATA_PROPERTY_COPY NSNumber *orientation; +@property SYMETADATA_PROPERTY_COPY NSNumber *xResolution; +@property SYMETADATA_PROPERTY_COPY NSNumber *yResolution; +@property SYMETADATA_PROPERTY_COPY NSNumber *resolutionUnit; +@property SYMETADATA_PROPERTY_COPY NSString *software; +@property SYMETADATA_PROPERTY_COPY NSArray *transferFunction; +@property SYMETADATA_PROPERTY_COPY NSString *dateTime; +@property SYMETADATA_PROPERTY_COPY NSString *artist; +@property SYMETADATA_PROPERTY_COPY NSString *hostComputer; +@property SYMETADATA_PROPERTY_COPY NSString *copyright; +@property SYMETADATA_PROPERTY_COPY NSArray *whitePoint; +@property SYMETADATA_PROPERTY_COPY NSArray *primaryChromaticities; +@property SYMETADATA_PROPERTY_COPY NSNumber *tileWidth; +@property SYMETADATA_PROPERTY_COPY NSNumber *tileLength; + +@end + diff --git a/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataTIFF.m b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataTIFF.m new file mode 100755 index 000000000..52d572769 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/SYPictureMetadata/SYMetadataTIFF.m @@ -0,0 +1,48 @@ +// +// SYMetadataTIFF.m +// SYPictureMetadataExample +// +// Created by Stan Chevallier on 12/13/12. +// Copyright (c) 2012 Syan. All rights reserved. +// + +#import "SYMetadataTIFF.h" +#import + +@implementation SYMetadataTIFF + ++ (NSDictionary *)JSONKeyPathsByPropertyKey +{ + return @{SYStringSel(compression): (NSString *)kCGImagePropertyTIFFCompression, + SYStringSel(photometricInterpretation):(NSString *)kCGImagePropertyTIFFPhotometricInterpretation, + SYStringSel(documentName): (NSString *)kCGImagePropertyTIFFDocumentName, + SYStringSel(imageDescription): (NSString *)kCGImagePropertyTIFFImageDescription, + SYStringSel(make): (NSString *)kCGImagePropertyTIFFMake, + SYStringSel(model): (NSString *)kCGImagePropertyTIFFModel, + SYStringSel(orientation): (NSString *)kCGImagePropertyTIFFOrientation, + SYStringSel(xResolution): (NSString *)kCGImagePropertyTIFFXResolution, + SYStringSel(yResolution): (NSString *)kCGImagePropertyTIFFYResolution, + SYStringSel(resolutionUnit): (NSString *)kCGImagePropertyTIFFResolutionUnit, + SYStringSel(software): (NSString *)kCGImagePropertyTIFFSoftware, + SYStringSel(transferFunction): (NSString *)kCGImagePropertyTIFFTransferFunction, + SYStringSel(dateTime): (NSString *)kCGImagePropertyTIFFDateTime, + SYStringSel(artist): (NSString *)kCGImagePropertyTIFFArtist, + SYStringSel(hostComputer): (NSString *)kCGImagePropertyTIFFHostComputer, + SYStringSel(copyright): (NSString *)kCGImagePropertyTIFFCopyright, + SYStringSel(whitePoint): (NSString *)kCGImagePropertyTIFFWhitePoint, + SYStringSel(primaryChromaticities): (NSString *)kCGImagePropertyTIFFPrimaryChromaticities, + + SYStringSel(tileWidth): (NSString *)kCGImagePropertyTIFFTileWidth, + SYStringSel(tileLength): (NSString *)kCGImagePropertyTIFFTileLength, + }; +} + ++ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key +{ + if ([key isEqualToString:SYStringSel(photometricInterpretation)]) + return [MTLValueTransformer sy_nonZeroIntegerValueTransformer]; + + return [super JSONTransformerForKey:key]; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/UIImage+scale.h b/thirdparty/flutter_image_compress/ios/Classes/UIImage+scale.h new file mode 100644 index 000000000..d8b9740e3 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/UIImage+scale.h @@ -0,0 +1,12 @@ +// +// Created by cjl on 2018/9/8. +// + +#import +#import + +@interface UIImage (scale) + +- (UIImage *)scaleWithMinWidth:(CGFloat)minWidth minHeight:(CGFloat)minHeight; +- (UIImage *)rotate:(CGFloat) rotate; +@end diff --git a/thirdparty/flutter_image_compress/ios/Classes/UIImage+scale.m b/thirdparty/flutter_image_compress/ios/Classes/UIImage+scale.m new file mode 100644 index 000000000..a74e818fa --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/Classes/UIImage+scale.m @@ -0,0 +1,74 @@ +// +// Created by cjl on 2018/9/8. +// + +#import "UIImage+scale.h" +#import "FlutterImageCompressPlugin.h" + +@implementation UIImage (scale) +-(UIImage *)scaleWithMinWidth: (CGFloat)minWidth minHeight:(CGFloat)minHeight { + float actualHeight = self.size.height; + float actualWidth = self.size.width; + float imgRatio = actualWidth/actualHeight; + float maxRatio = minWidth/minHeight; + float scaleRatio = 1; + + if(imgRatio < maxRatio) { + scaleRatio = minWidth / actualWidth; + } else { + scaleRatio = minHeight / actualHeight; + } + scaleRatio = fminf(1, scaleRatio); + + actualWidth = floor(scaleRatio * actualWidth); + actualHeight = floor(scaleRatio * actualHeight); + + CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight); + UIGraphicsBeginImageContext(rect.size); + [self drawInRect:rect]; + UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + if([FlutterImageCompressPlugin showLog]){ + NSLog(@"scale = %.2f", scaleRatio); + NSLog(@"dst width = %.2f", rect.size.width); + NSLog(@"dst height = %.2f", rect.size.height); + } + + return newImage; +} + +- (UIImage *)rotate:(CGFloat) rotate{ + return [self imageRotatedByDegrees:self deg:rotate]; +} + +- (UIImage *)imageRotatedByDegrees:(UIImage*)oldImage deg:(CGFloat)degrees{ + if([FlutterImageCompressPlugin showLog]) { + NSLog(@"will rotate %f",degrees); + } + + // calculate the size of the rotated view's containing box for our drawing space + UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,oldImage.size.width, oldImage.size.height)]; + CGAffineTransform t = CGAffineTransformMakeRotation(degrees * M_PI / 180); + rotatedViewBox.transform = t; + CGSize rotatedSize = rotatedViewBox.frame.size; + // Create the bitmap context + UIGraphicsBeginImageContext(rotatedSize); + CGContextRef bitmap = UIGraphicsGetCurrentContext(); + + // Move the origin to the middle of the image so we will rotate and scale around the center. + CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); + + // // Rotate the image context + CGContextRotateCTM(bitmap, (degrees * M_PI / 180)); + + // Now, draw the rotated/scaled image into the context + CGContextScaleCTM(bitmap, 1.0, -1.0); + CGContextDrawImage(bitmap, CGRectMake(-oldImage.size.width / 2, -oldImage.size.height / 2, oldImage.size.width, oldImage.size.height), [oldImage CGImage]); + + UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return newImage; +} + +@end diff --git a/thirdparty/flutter_image_compress/ios/flutter_image_compress.podspec b/thirdparty/flutter_image_compress/ios/flutter_image_compress.podspec new file mode 100644 index 000000000..906fceed5 --- /dev/null +++ b/thirdparty/flutter_image_compress/ios/flutter_image_compress.podspec @@ -0,0 +1,22 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'flutter_image_compress' + s.version = '0.0.1' + s.summary = 'A new flutter plugin project.' + s.description = <<-DESC +A new flutter plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.dependency 'Mantle' + s.ios.deployment_target = '8.0' + s.dependency 'SDWebImageWebPCoder' +end + diff --git a/thirdparty/flutter_image_compress/lib/flutter_image_compress.dart b/thirdparty/flutter_image_compress/lib/flutter_image_compress.dart new file mode 100644 index 000000000..8885cc1f1 --- /dev/null +++ b/thirdparty/flutter_image_compress/lib/flutter_image_compress.dart @@ -0,0 +1,234 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'src/compress_format.dart'; +import 'src/validator.dart'; + +export 'src/compress_format.dart'; + +/// Image Compress +/// +/// static method will help you compress image +/// +/// most method will return [Uint8List] +/// +/// You can use `Image.memory` to display image +/// ```dart +/// Uint8List uint8List; +/// ImageProvider provider = MemoryImage(uint8List); +/// ``` +/// +/// or +/// +/// ```dart +/// Uint8List uint8List; +/// Image.momory(uint8List) +/// ``` +/// The returned image will retain the proportion of the original image. +/// +/// Compress image will remove EXIF. +/// +/// image result is jpeg format. +/// +/// support rotate +/// +class FlutterImageCompress { + static const MethodChannel _channel = + const MethodChannel('flutter_image_compress'); + + static Validator _validator = Validator(_channel); + + static Validator get validator => _validator; + + static set showNativeLog(bool value) { + _channel.invokeMethod("showLog", value); + } + + /// Compress image from [Uint8List] to [Uint8List]. + static Future compressWithList( + Uint8List image, { + int minWidth = 1920, + int minHeight = 1080, + int quality = 95, + int rotate = 0, + int inSampleSize = 1, + bool autoCorrectionAngle = true, + CompressFormat format = CompressFormat.jpeg, + bool keepExif = false, + }) async { + assert( + image != null, + "A non-null Uint8List must be provided to FlutterImageCompress.", + ); + if (image == null) { + throw "The image is null."; + } + if (image.isEmpty) { + throw "The image is empty."; + } + + final support = await _validator.checkSupportPlatform(format); + if (!support) { + throw "The image is not support."; + } + + final result = await _channel.invokeMethod("compressWithList", [ + image, + minWidth, + minHeight, + quality, + rotate, + autoCorrectionAngle, + _convertTypeToInt(format), + keepExif, + inSampleSize, + ]); + + return result; + } + + /// Compress file of [path] to [Uint8List]. + static Future compressWithFile( + String path, { + int minWidth = 1920, + int minHeight = 1080, + int inSampleSize = 1, + int quality = 95, + int rotate = 0, + bool autoCorrectionAngle = true, + CompressFormat format = CompressFormat.jpeg, + bool keepExif = false, + }) async { + assert( + path != null, + "A non-null String must be provided to FlutterImageCompress.", + ); + if (path == null || !File(path).existsSync()) { + throw "Image file ($path) does not exist."; + } + + final support = await _validator.checkSupportPlatform(format); + if (!support) { + return null; + } + + final result = await _channel.invokeMethod("compressWithFile", [ + path, + minWidth, + minHeight, + quality, + rotate, + autoCorrectionAngle, + _convertTypeToInt(format), + keepExif, + inSampleSize, + ]); + return result; + } + + /// From [path] to [targetPath] + static Future compressAndGetFile( + String path, + String targetPath, { + int minWidth = 1920, + int minHeight = 1080, + int inSampleSize = 1, + int quality = 95, + int rotate = 0, + bool autoCorrectionAngle = true, + CompressFormat format = CompressFormat.jpeg, + bool keepExif = false, + }) async { + assert( + path != null, + "A non-null String must be provided to FlutterImageCompress.", + ); + if (path == null || !File(path).existsSync()) { + throw "Image file does not exist"; + } + assert(targetPath != null, "The target path must be null."); + assert( + targetPath != path, "Target path and source path cannot be the same."); + + _validator.checkFileNameAndFormat(targetPath, format); + + final support = await _validator.checkSupportPlatform(format); + if (!support) { + return null; + } + + final String result = + await _channel.invokeMethod("compressWithFileAndGetFile", [ + path, + minWidth, + minHeight, + quality, + targetPath, + rotate, + autoCorrectionAngle, + _convertTypeToInt(format), + keepExif, + inSampleSize, + ]); + + if (result == null) { + return null; + } + + return File(result); + } + + /// From [asset] to [Uint8List] + static Future compressAssetImage( + String assetName, { + int minWidth = 1920, + int minHeight = 1080, + int quality = 95, + int rotate = 0, + bool autoCorrectionAngle = true, + CompressFormat format = CompressFormat.jpeg, + bool keepExif = false, + }) async { + assert( + assetName != null, + "A non-null String must be provided to FlutterImageCompress.", + ); + if (assetName == null) { + return null; + } + + final support = await _validator.checkSupportPlatform(format); + if (!support) { + return null; + } + + final img = AssetImage(assetName); + final config = ImageConfiguration(); + + AssetBundleImageKey key = await img.obtainKey(config); + final ByteData data = await key.bundle.load(key.name); + + final uint8List = data.buffer.asUint8List(); + + if (uint8List == null || uint8List.isEmpty) { + return null; + } + + return compressWithList( + uint8List, + minHeight: minHeight, + minWidth: minWidth, + quality: quality, + rotate: rotate, + autoCorrectionAngle: autoCorrectionAngle, + format: format, + keepExif: keepExif, + ); + } +} + +int _convertTypeToInt(CompressFormat format) => format.index; diff --git a/thirdparty/flutter_image_compress/lib/src/compress_format.dart b/thirdparty/flutter_image_compress/lib/src/compress_format.dart new file mode 100644 index 000000000..1ee3c51a3 --- /dev/null +++ b/thirdparty/flutter_image_compress/lib/src/compress_format.dart @@ -0,0 +1,6 @@ +/// Webp only support android. +/// +/// heic: +/// - iOS: support iOS11+. +/// - android: API 28+, and May require hardware encoder support, does not guarantee that all devices above API28 are available. Use [HeifWriter](https://developer.android.com/reference/androidx/heifwriter/HeifWriter.html) +enum CompressFormat { jpeg, png, heic, webp } diff --git a/thirdparty/flutter_image_compress/lib/src/errors.dart b/thirdparty/flutter_image_compress/lib/src/errors.dart new file mode 100644 index 000000000..bfb381752 --- /dev/null +++ b/thirdparty/flutter_image_compress/lib/src/errors.dart @@ -0,0 +1,11 @@ +class UnsupportError extends Error { + final String message; + + UnsupportError(this.message); +} + +class CompressError extends Error { + final String message; + + CompressError(this.message); +} diff --git a/thirdparty/flutter_image_compress/lib/src/validator.dart b/thirdparty/flutter_image_compress/lib/src/validator.dart new file mode 100644 index 000000000..bfc14cb0a --- /dev/null +++ b/thirdparty/flutter_image_compress/lib/src/validator.dart @@ -0,0 +1,80 @@ +import 'dart:io'; +import 'dart:async'; + +import 'package:flutter/services.dart'; + +import 'compress_format.dart'; + +class Validator { + final MethodChannel channel; + Validator(this.channel); + + bool ignoreCheckExtName = false; + bool ignoreCheckSupportPlatform = false; + + void checkFileNameAndFormat(String name, CompressFormat format) { + if (ignoreCheckExtName) { + return; + } + name = name.toLowerCase(); + if (format == CompressFormat.jpeg) { + assert((name.endsWith(".jpg") || name.endsWith(".jpeg")), + "The jpeg format name must end with jpg or jpeg."); + } else if (format == CompressFormat.png) { + assert(name.endsWith(".png"), "The jpeg format name must end with png."); + } else if (format == CompressFormat.heic) { + assert( + name.endsWith(".heic"), "The heic format name must end with heic."); + } else if (format == CompressFormat.webp) { + assert( + name.endsWith(".webp"), "The webp format name must end with webp."); + } + } + + Future checkSupportPlatform(CompressFormat format) async { + if (ignoreCheckSupportPlatform) { + return true; + } + if (format == CompressFormat.heic) { + if (Platform.isIOS) { + final String version = await channel.invokeMethod("getSystemVersion"); + final firstVersion = version.split(".")[0]; + final result = int.parse(firstVersion) >= 11; + final msg = "The heic format only support iOS 11.0+"; + assert(result, msg); + _checkThrowError(result, msg); + return result; + } else if (Platform.isAndroid) { + final int version = await channel.invokeMethod("getSystemVersion"); + final result = version >= 28; + final msg = "The heic format only support android API 28+"; + assert(result, msg); + _checkThrowError(result, msg); + return result; + } else { + final msg = "The heic format only support android and iOS."; + assert(Platform.isAndroid || Platform.isIOS, msg); + _checkThrowError(false, msg); + return false; + } + } else if (format == CompressFormat.webp) { + if (Platform.isAndroid || Platform.isIOS) { + return true; + } + + var msg = "The webp format only support android and iOS."; + + _checkThrowError(false, msg); + + return false; + } + + return true; + } + + void _checkThrowError(bool result, String msg) { + if (!result) { + throw UnsupportedError(msg); + } + } +} diff --git a/thirdparty/flutter_image_compress/pubspec.yaml b/thirdparty/flutter_image_compress/pubspec.yaml new file mode 100644 index 000000000..88166f8b1 --- /dev/null +++ b/thirdparty/flutter_image_compress/pubspec.yaml @@ -0,0 +1,17 @@ +name: flutter_image_compress +description: compress image with native code(objc kotlin), it's faster. This library can work on android/ios. +version: 0.7.0 +author: caijinglong +homepage: https://github.com/OpenFlutter/flutter_image_compress + +environment: + sdk: ">=2.0.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + +flutter: + plugin: + androidPackage: com.example.flutterimagecompress + pluginClass: FlutterImageCompressPlugin