Add flutter_image_compress as a direct dependency

This commit is contained in:
Vishnu Mohandas 2021-01-21 16:19:12 +05:30
parent b699a94b58
commit 4c68c9603f
185 changed files with 7455 additions and 1 deletions

@ -1 +0,0 @@
Subproject commit f130a414e345fb54f24a69e29a9a02afc8ad38ac

View file

@ -0,0 +1,3 @@
*.dart linguist-language=Dart
*.m linguist-language=Dart
*.h linguist-language=Dart

View file

@ -0,0 +1,12 @@
.DS_Store
.dart_tool/
.packages
.pub/
pubspec.lock
build/
.idea/
.flutter-plugins-dependencies
.vscode/settings.json
flutter_export_environment.sh

View file

@ -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"
}
]
}

View file

@ -0,0 +1,164 @@
# CHANGELOG
## 0.7.0
- Fix
- Fix momory leaked for android.
- Support android v2 plugin.
**Breaking Change**:
- Replace `List<int>` 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

View file

@ -0,0 +1,5 @@
# CONTRIBUTING
Please submit changes to master branch.
And make sure your code is willing to comply with MIT style.

View file

@ -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.

View file

@ -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<int>` 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
QDart already has image compression libraries. Why use native?
AFor 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<Uint8List> 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<File> 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<Uint8List> 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<Uint8List> 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<int>` and `Uint8List`
You may need to convert `List<int>` 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<int> 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<int> 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<Uint8List> 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)

View file

@ -0,0 +1,13 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.settings
.classpath
.project

View file

@ -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'
}

View file

@ -0,0 +1 @@
org.gradle.jvmargs=-Xmx1536M

View file

@ -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

View file

@ -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" "$@"

View file

@ -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

View file

@ -0,0 +1 @@
rootProject.name = 'flutter_image_compress'

View file

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.flutterimagecompress">
<uses-sdk tools:overrideLibrary="androidx.heifwriter"/>
</manifest>

View file

@ -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<Boolean>()
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
}
}

View file

@ -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<Any> = call.arguments as List<Any>
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<Any> = call.arguments as List<Any>
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()
}
}
}
}

View file

@ -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<Any> = call.arguments as List<Any>
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()
}
}
}
}

View file

@ -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)
}
}
}

View file

@ -0,0 +1,5 @@
package com.example.flutterimagecompress.exception
import java.lang.Exception
class CompressError(message: String) : Exception(message)

View file

@ -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
}
}
}

View file

@ -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<String> 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;
}
}
}

View file

@ -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
}

View file

@ -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<FormatHandler>()
fun registerFormat(handler: FormatHandler) {
formatMap.append(handler.type, handler)
}
fun findFormat(formatIndex: Int): FormatHandler? {
return formatMap.get(formatIndex)
}
}

View file

@ -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)
}

View file

@ -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)
}
}
}

View file

@ -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())
}
}

View file

@ -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")
}
}

View file

@ -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)
}
}

View file

@ -0,0 +1,15 @@
.DS_Store
.dart_tool/
.packages
.pub/
build/
.flutter-plugins
.idea
.settings
.classpath
.project

View file

@ -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

View file

@ -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/).

View file

@ -0,0 +1,10 @@
*.iml
*.class
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
GeneratedPluginRegistrant.java

View file

@ -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'
}

View file

@ -0,0 +1,39 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flutterimagecompressexample">
<!-- The INTERNET permission is required for development. Specifically,
flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="flutter_image_compress_example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View file

@ -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);
}

View file

@ -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 {
}

View file

@ -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 {
}

View file

@ -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)
}
}

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

View file

@ -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
}

View file

@ -0,0 +1,6 @@
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.debug.obsoleteApi=true

View file

@ -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

View file

@ -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 "$@"

View file

@ -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

View file

@ -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
}

View file

@ -0,0 +1,2 @@
build
.last_goflutter_check

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -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{}))
}

View file

@ -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,
}))
}

View file

@ -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
}

View file

@ -0,0 +1,9 @@
package main
import (
"github.com/go-flutter-desktop/go-flutter"
)
var options = []flutter.Option{
flutter.WindowInitialDimensions(800, 1280),
}

View file

@ -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

View file

@ -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=

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -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/

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>

View file

@ -0,0 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View file

@ -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

View file

@ -0,0 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View file

@ -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

View file

@ -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

View file

@ -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 = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
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 = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
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 = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
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 = "<group>";
};
587FC836BA6286FCA8336FE7 /* Pods */ = {
isa = PBXGroup;
children = (
26D8CA1FA8483F82FD0C13FB /* Pods-Runner.debug.xcconfig */,
104B390780BA384E19B9CD64 /* Pods-Runner.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
587FC836BA6286FCA8336FE7 /* Pods */,
1F80C4BD5877066B2B68A73E /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
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 = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
97C146F21CF9000F007C117D /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* 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 = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* 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 */;
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>

View file

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -0,0 +1,6 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end

View file

@ -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

View file

@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -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"
}
}

Some files were not shown because too many files have changed in this diff Show more