sunzxyong / tiny Goto Github PK
View Code? Open in Web Editor NEWan image compression framework.(一个高保真、高压缩比的图片压缩框架)
License: Apache License 2.0
an image compression framework.(一个高保真、高压缩比的图片压缩框架)
License: Apache License 2.0
Tiny.FileCompressOptions options = new Tiny.FileCompressOptions();
Tiny.getInstance().source("").batchAsFile().withOptions(options).batchCompress(new FileBatchCallback() {
@OverRide
public void callback(boolean isSuccess, String[] outfile) {
//return the batch compressed file path
}
});
因为你的demo里面写的是数组,长度都固定了,我现在不知道用户要传几张,只能传集合,
手机:三星 分辨率:1080x1920 系统:6.0.1
拍照后进行压缩:压缩3456 x 4608的图片时,回调状态成功,但是压缩后的图还是跟原图一样大
现在内部的压缩策略应该是不考虑原图片的长宽比的。
所以如果有一张比例1:10的图片,直接就被压缩到非常模糊。
压缩的时候,最好把图片统一处理成 纵向显示,而不是横向显示
java.io.FileNotFoundException: http:/img.gank.io/da234724-80ab-4059-ae3b-52831508e45c?imageView2/0/w/400: open failed: ENOENT (No such file or directory) 请问是什么原因???
我的代码是下面这样的
Tiny.BitmapCompressOptions options = new Tiny.BitmapCompressOptions();
Tiny.getInstance().source("").asBitmap().withOptions(options).compress(new BitmapCallback() {
@OverRide
public void callback(boolean isSuccess, Bitmap bitmap) {
//return the compressed bitmap object
}
});
压缩后图片大小都没变呀,大小还是那么大
您好,非常感谢您上次回答我的疑问,看了你的demo后我实现了加载图片,速度也还可以,但是在我虚拟机上出现了oom,具体错误如下:
Alloc concurrent mark sweep GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 0% free, 99MB/99MB, paused 265us total 10.030ms
I/art: WaitForGcToComplete blocked for 255.761ms for cause Alloc
I/art: Starting a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
W/art: Throwing OutOfMemoryError "Failed to allocate a 28 byte allocation with 0 free bytes and 3GB until OOM" (recursive case)
I/art: Waiting for a blocking GC Alloc
W/art: "tiny-compress-thread-4" prio=5 tid=27 Runnable
W/art: | group="main" sCount=0 dsCount=0 obj=0x22c0f820 self=0xded82a00
W/art: | sysTid=8819 nice=0 cgrp=default sched=0/0 handle=0xdc1fa930
W/art: | state=R schedstat=( 2617287020 851805915 3970 ) utm=93 stm=168 core=1 HZ=100
W/art: | stack=0xdc0f8000-0xdc0fa000 stackSize=1038KB
W/art: | held mutexes= "mutator lock"(shared held)
W/art: native: #00 pc 0058b0e2 /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits >&, int, char const*, art::ArtMethod*, void*)+226)
W/art: native: #1 pc 00551c3e /system/lib/libart.so (art::Thread::ThrowOutOfMemoryError(char const*)+542)
W/art: native: #2 pc 0029b73d /system/lib/libart.so (art::gc::Heap::ThrowOutOfMemoryError(art::Thread*, unsigned int, art::gc::AllocatorType)+1559)
W/art: native: #3 pc 002a4ad2 /system/lib/libart.so (art::gc::Heap::AllocateInternalWithGc(art::Thread*, art::gc::AllocatorType, unsigned int, unsigned int*, unsigned int*, unsigned int*, art::mirror::Class**)+5218)
W/art: native: #4 pc 001a185d /system/lib/libart.so (art::mirror::Class::AllocObject(art::Thread*)+1677)
W/art: native: #5 pc 0054db66 /system/lib/libart.so (art::Thread::ThrowNewWrappedException(char const*, char const*)+774)
W/art: native: #6 pc 00551cfa /system/lib/libart.so (art::Thread::ThrowOutOfMemoryError(char const*)+730)
W/art: native: #7 pc 0029b73d /system/lib/libart.so (art::gc::Heap::ThrowOutOfMemoryError(art::Thread*, unsigned int, art::gc::AllocatorType)+1559)
W/art: native: #8 pc 002a4ad2 /system/lib/libart.so (art::gc::Heap::AllocateInternalWithGc(art::Thread*, art::gc::AllocatorType, unsigned int, unsigned int*, unsigned int*, unsigned int*, art::mirror::Class**)+5218)
W/art: native: #9 pc 00445884 /system/lib/libart.so (art::mirror::String::AllocFromModifiedUtf8(art::Thread*, int, char const*)+2420)
W/art: native: #10 pc 0044635d /system/lib/libart.so (art::mirror::String::AllocFromModifiedUtf8(art::Thread*, char const*)+47)
W/art: native: #11 pc 00408aec /system/lib/libart.so (art::JNI::NewStringUTF(_JNIEnv*, char const*)+540)
W/art: native: #12 pc 0017c545 /system/lib/libart.so (art::CheckJNI::NewStringUTF(_JNIEnv*, char const*)+632)
W/art: native: #13 pc 000dd23e /system/lib/libandroid_runtime.so (getMimeTypeString(_JNIEnv*, SkImageDecoder::Format)+94)
W/art: native: #14 pc 000ddedd /system/lib/libandroid_runtime.so (???)
W/art: native: #15 pc 000de8b5 /system/lib/libandroid_runtime.so (???)
W/art: native: #16 pc 00d29a32 /data/dalvik-cache/x86/system@[email protected] (Java_android_graphics_BitmapFactory_nativeDecodeByteArray___3BIILandroid_graphics_BitmapFactory_00024Options_2+182)
W/art: native: #17 pc 0184c747 /dev/ashmem/dalvik-main space 1 (deleted) (???)
W/art: at android.graphics.BitmapFactory.nativeDecodeByteArray(Native method)
W/art: at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:522)
W/art: at com.zxy.tiny.core.BitmapCompressor.sampleCompress(BitmapCompressor.java:201)
W/art: at com.zxy.tiny.core.BitmapCompressor.compress(BitmapCompressor.java:84)
W/art: at com.zxy.tiny.callable.BitmapCompressCallableTasks$UriAsBitmapCallable$1.callback(BitmapCompressCallableTasks.java:102)
W/art: at com.zxy.tiny.core.HttpUrlConnectionFetcher.fetch(HttpUrlConnectionFetcher.java:82)
W/art: at com.zxy.tiny.callable.BitmapCompressCallableTasks$UriAsBitmapCallable.call(BitmapCompressCallableTasks.java:99)
W/art: at com.zxy.tiny.callable.BitmapCompressCallableTasks$UriAsBitmapCallable.call(BitmapCompressCallableTasks.java:87)
W/art: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/art: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/art: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/art: at com.zxy.tiny.core.CompressThreadFactory$1.run(CompressThreadFactory.java:28)
W/art: at java.lang.Thread.run(Thread.java:818)
D/skia: --- OOM in getMimeTypeString()
I/art: Waiting for a blocking GC Alloc
I/art: Clamp target GC heap from 115MB to 99MB
I/art: Alloc partial concurrent mark sweep GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 0% free, 99MB/99MB, paused 618us total 16.222ms
I/art: WaitForGcToComplete blocked for 48.670ms for cause Alloc
I/art: Starting a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
如题,libtiny.so是否开源,项目中没有看到.c和cpp的源码。
最好能够支持旋转
请教一个与项目无关的题外话,您的文章有关图片文件的二进制是用什么软件查看的?
http://zhengxiaoyong.me/2017/04/23/%E4%B9%9F%E8%B0%88%E5%9B%BE%E7%89%87%E5%8E%8B%E7%BC%A9/
请问这里面提到的PNG文件结构是用什么查看的?是用UltraEdit吗?
我在项目中使用了腾讯的bugly插件,给我返回了一个标题为 SIGABRT 这个的错误。机型是 荣耀 CAM TL00 Android 6.0
1 #00 pc 000000000006aec4 /system/lib64/libc.so (tgkill+8) [arm64-v8a]
2 #01 pc 00000000000690a4 /system/lib64/libc.so (pthread_kill+68) [arm64-v8a]
3 #02 pc 000000000002208c /system/lib64/libc.so (raise+28) [arm64-v8a]
4 #03 pc 000000000001c998 /system/lib64/libc.so (abort+60) [arm64-v8a]
5 #04 pc 000000000040e728 /system/lib64/libart.so (art::Runtime::Abort()+324) [arm64-v8a]
6 #05 pc 000000000010dfa4 /system/lib64/libart.so (art::LogMessage::~LogMessage()+3136) [arm64-v8a]
7 #06 pc 00000000002e76a0 /system/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+2080) [arm64-v8a]
8 #07 pc 00000000002e7b20 /system/lib64/libart.so (art::JavaVMExt::JniAbortV(char const*, char const*, std::__va_list)+116) [arm64-v8a]
9 #08 pc 0000000000119ddc /system/lib64/libart.so (art::JValue art::interpreter::ExecuteSwitchImpl<true, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)+48684) [arm64-v8a]
10 #09 pc 0000000000120c8c /system/lib64/libart.so (art_quick_set_obj_instance+12) [arm64-v8a]
11 #10 pc 000000000013a4cc /system/lib64/libart.so (art::ReaderWriterMutex::ExclusiveLockWithTimeout(art::Thread*, long, int)+452) [arm64-v8a]
12 #11 pc 000000000013ad54 /system/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+632) [arm64-v8a]
13 #12 pc 00000000000c3d9c /system/lib64/libandroid_runtime.so (doDecode(_JNIEnv*, SkStreamRewindable*, _jobject*, _jobject*)+1060) [arm64-v8a]
14 #13 pc 00000000000c45a4 /system/lib64/libandroid_runtime.so (android::NativeInputEventSender::initialize()+40) [arm64-v8a]
15 #14 pc 00000000032e2210 /data/dalvik-cache/arm64/system@[email protected] (oatexec+15000080) [arm64-v8a]
16 java:
17 android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:580)
18 com.zxy.tiny.core.BitmapCompressor.sampleCompress(BitmapCompressor.java:228)
19 com.zxy.tiny.core.BitmapCompressor.compress(BitmapCompressor.java:106)
20 com.zxy.tiny.core.FileCompressor.compress(FileCompressor.java:38)
21 com.zxy.tiny.callable.FileCompressCallableTasks$FileAsFileCallable.call(FileCompressCallableTasks.java:76)
22 com.zxy.tiny.callable.FileCompressCallableTasks$FileAsFileCallable.call(FileCompressCallableTasks.java:60)
23 java.util.concurrent.FutureTask.run(FutureTask.java:237)
24 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
25 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
26 com.zxy.tiny.core.CompressThreadFactory$1.run(CompressThreadFactory.java:28)
27 java.lang.Thread.run(Thread.java:833)
28 java pending exception:
29 [Native crash above happened with a java pending exception as following]
30 java.lang.OutOfMemoryError: Failed to allocate a 12979212 byte allocation with 4194304 free bytes and 11MB until OOM
31 android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
32 android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:580)
33 com.zxy.tiny.core.BitmapCompressor.sampleCompress(BitmapCompressor.java:228)
34 com.zxy.tiny.core.BitmapCompressor.compress(BitmapCompressor.java:106)
35 com.zxy.tiny.core.FileCompressor.compress(FileCompressor.java:38)
36 com.zxy.tiny.callable.FileCompressCallableTasks$FileAsFileCallable.call(FileCompressCallableTasks.java:76)
37 com.zxy.tiny.callable.FileCompressCallableTasks$FileAsFileCallable.call(FileCompressCallableTasks.java:60)
38 java.util.concurrent.FutureTask.run(FutureTask.java:237)
39 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
40 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
41 com.zxy.tiny.core.CompressThreadFactory$1.run(CompressThreadFactory.java:28)
42 java.lang.Thread.run(Thread.java:833)
下面是腾讯的Bugly给出的解决方案。
解决方案
abort program
SIG是信号名的通用前缀。ABRT是abort program的缩写。
当操作系统发现不安全的情况时,它能够对这种情况进行更多的控制,必要的话,它能要求进程进行清理工作。在调试造成此信号的底层错误时,并没有什么妙招。 如 cocos2d 或 UIKit 等框架通常会在特定的前提条件没有满足或一些糟糕的情况出现时调用 C 函数 abort (由它来发送此信号)。
如果是iOS系统:
发生在UIApplication WillTerminate 时,是主动退出应用时发生的,所以对用户没什么实际影响。
iOS10访问相册时发生,目前只发生在iOS10+系统,需要修改工程plist文件,加入访问权限提示信息。
补充:iOS 10 has updated privacy policy and implemented new privacy rules. You have to update your Info.plist app with this following fields by authorisation asked.
libtiny.so 对应的源码有吗,是否可以开源?
Your app(s) are using an unsafe implementation of the HostnameVerifier interface. You can find more information about how resolve the issue in this Google Help Center article.
https://support.google.com/faqs/answer/7188426
HttpUrlConnectionFetcher.java
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
在阅读完《也谈图片压缩》这篇文章后受益匪浅,感谢作者的分享!之前也看过一篇有关于Android使用JNI的方式压缩图片的文章,都会存在一个问题就是瞬间占用大量内存而无法主动释放,多的一下能增加50M之多,在应用已经使用比较高的情况下很容易造成OOM,不知道作者有没有什么方案?
Have you considered adding the option to compress the images in a blocking fashion for times when we are already processing the image in a background thread and would prefer to not spawn a new background thread and callback?
Is it possible to set a MAX size limit for the returned image? If not, what is the best way to make sure that the image is maximum quality under a certain size? Thank you for the great library!
为什么我在library dependence中搜不到com.zxy.android这个
如题
设置 RGB565 后
originPath='/storage/emulated/0/DCIM/Camera/IMG_20170204_120533.jpg',size=974704, format='jpg', width=3024, height=4032,
设置 ARGB8888 后
originPath='/storage/emulated/0/DCIM/Camera/IMG_20170204_120533.jpg', size=917344, format='jpg', width=3024, height=4032,
不应该 565会更小吗?
比如设置图片为屏幕宽度进行比例压缩,或指定宽高在进行压缩
在批量压缩 需要配置最大边长 希望可以修改为调用者动态修改 感谢
Error:Execution failed for task ':app:transformClassesWithJarMergingForG009Product'.
com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: com/zxy/libjpegturbo/JpegTurboCompressor.class
如果压缩过程中出现异常,比如存储空间不够导致无法压缩,你直接屏蔽了异常,根本拿不到,app无法进行友好提示
需求:一次性压缩多张图片,并且覆盖源文件,图片路径包括名字都不该变
在压缩单张图片的时候可以自定义保存路径,compressOptions.outfile,但是在多图压缩中却没办法自定义,压缩参数是一个数组,而compressOptions并没有对应的保存路径的数组属性。我想过使用循环压缩单张的方法,但是源码中应该是使用了线程池的,而且这样循环必定OOM。不知道作者有没有更好的方案!
我在自己的项目中发现 红米note 有问题 Android 4.4
07-31 20:42:34.723 28333-28871/com.xxx..imagepicker W/ContextImpl: Failed to ensure directory: /storage/sdcard1/Android/data/com.xx.imagepicker/files: 400
07-31 20:42:34.723 28333-28871/com.xxx.imagepicker W/dalvikvm: Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/xxx/plugin/imagepicker/libjpegturbo/JpegTurboCompressor;
在Nexus 5x 中正常
感谢提出Issues的同学,在此版本做了一个api的改变,外抛了压缩失败后异常信息的抛出,便于排查问题。
【注】这次更新没有用@Deprecated
方式进行callback
方法的兼容,主要考虑api变化不大,且需兼容之前的需增加额外的接口以及大部分代码,导致业务层api使用代码过多,所以版本连升3个版本号。
api改动仅仅增加了一个Throwable参数,
由原先:
void callback(boolean isSuccess, Bitmap bitmap);
变为:
void callback(boolean isSuccess, Bitmap bitmap, Throwable t);
所以业务逻辑可不变即可平滑升级。
提个建议,增加个同步的方法,有些时候需要用到同步的方法来压缩
图片比较多,平时没有看很久,今天在虚拟机上加载很多图片,结果又出现了一次OOM,具体错误如下:
Clamp target GC heap from 107MB to 96MB
I/art: Alloc partial concurrent mark sweep GC freed 122(6KB) AllocSpace objects, 2(5MB) LOS objects, 4% free, 91MB/96MB, paused 308us total 9.215ms
I/art: WaitForGcToComplete blocked for 239.242ms for cause Alloc
I/art: Starting a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
E/AndroidRuntime: FATAL EXCEPTION: tiny-compress-thread-5
Process: com.pro.head, PID: 2175
java.lang.OutOfMemoryError: Failed to allocate a 17 byte allocation with 0 free bytes and 3GB until OOM
at com.zxy.tiny.core.CompressFutureTask.done(CompressFutureTask.java:36)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.set(FutureTask.java:205)
at com.zxy.tiny.core.CompressFutureTask.set(CompressFutureTask.java:41)
at java.util.concurrent.FutureTask.run(FutureTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at com.zxy.tiny.core.CompressThreadFactory$1.run(CompressThreadFactory.java:28)
at java.lang.Thread.run(Thread.java:818)
I/art: Alloc sticky concurrent mark sweep GC freed 102(31KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 92MB/96MB, paused 1.352ms total 6.557ms
D/skia: --- OOM in getMimeTypeString()
I/art: WaitForGcToComplete blocked for 456.143ms for cause Alloc
I/art: Starting a blocking GC Alloc
I/art: WaitForGcToComplete blocked for 307.786ms for cause Alloc
I/art: Starting a blocking GC Alloc
I/art: Waiting for a blocking GC Alloc
请问 compile 'com.zxy.android:tiny:${LAST_VERSION}' 这个${LAST_VERSION} 错误 应该写多少了?
如题,同步方法特定场景可能需要,希望有空完善下
...
我貌似没有看到有介绍说可以压缩gif图片还能正常播放的,刚用luban试了一下压缩完就不能播放了
com.zxy.tiny.core.HttpUrlConnectionFetcher$TinyTrustManager
May Should check the SSL certificate validation.
public void callback(boolean isSuccess, String outfile, Throwable t){}
这个回调方法中isSuccess 返回fslse,
ndk {
abiFilters 'armeabi-v7a','x86'//or armeabi、arm64-v8a、x86
}
我加了这句话后,项目里的其他.so包就会报错。
导入后 apk体积增大多少,这个批量压缩(9张)的时间一般多长
比如我用的fresco里面似乎已经有libjpeg-turbo,有没有什么办法,直接调用而不需要再加入tiny里的libjpeg-turbo,这样打包后体积能小很多
public void callback(boolean isSuccess, String outfile) {}
How can I know what is the error for isSucess false?
Where is the C, C++ JNI source code of the tiny lib?
any file output from compression i can't see it in the image resource
as follow
`
Tiny.FileCompressOptions options = new Tiny.FileCompressOptions();
Tiny.getInstance().source(orignalFilePath).asFile().withOptions(options).compress(new FileCallback() {
@OverRide
public void callback(boolean isSuccess, final String outfile) {
if (isSuccess) {
Log.d("Tiny", "isSuccess");
Log.d("Tiny", outfile);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@OverRide
public void run() {
//Do something after 100ms
Picasso.with(MainActivity.this)
.load(outfile)
.into(comperessedImge);
txtCompressedImgSize.setText(getFileSize(outfile) + "");
}
}, 1000);
} else {
Log.d("Matisse", "failed");
}
}
});
`
在联想的TAB3 10 这款pad上使用会出现如题所示的问题。
Wow, the images compressed by this library are amazing in quality! Almost indistinguishable from the originals but 1/50th the size!
My question is about the isKeepSampling option. What exactly does this option do? I assume that it means whether or not to keep the original image width and height. But when I set it to true, a 5520x4140 image was compressed to 960x1280. I thought the option would keep the dimensions at 5520x4140. So, what exactly does this option do? I notice no changes in the output file when setting it to true or false.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.