waynejo / android-ndk-gif Goto Github PK
View Code? Open in Web Editor NEWGIF library built with ndk and gradle in aar format for usage with android gradle build system.
License: Other
GIF library built with ndk and gradle in aar format for usage with android gradle build system.
License: Other
there is part of my code:
if (gifEncoder != null) {
Bitmap bitmap = createBitmapFromPixelsBuffer();
bitmap = Bitmap.createScaledBitmap(bitmap, scaleWidth, scaleHeight, true);
gifEncoder.encodeFrame(bitmap, delay);
// just for check log
if (bitmap == null){
Log.e(TAG, "encodeFrame: is null" + delay);
}else {
Log.e(TAG, "encodeFrame: not null" + delay);
}
}
when i set other two type,it work will,just in ENCODING_TYPE_STABLE_HIGH_MEMORY type,it's give me empty gif file,what's wrong?
delay is faster between each frame by using Gifdecoder.decode.delay(index)
try out this gif
http://cdn.appcloudbox.net/keyboardarts/download/stickers/LoveGif/LoveGif/LoveGif-06.gif
I just use your jni files , compare with your aar, it takes much more time, i do not find out the reason. i wonder whether it because i use debug mode other than release mode
Hi, I want to get one frame from gif. I used the code as below. But it crashed on release build type. It works fine on debug.
public static String getOneFrameFromGif(File file){
GifDecoder decoder = new GifDecoder();
GifImageIterator imageIterator = null;
try{
imageIterator = decoder.loadUsingIterator(file.getAbsolutePath());
//temp file/
String targetPath = FileUtil.INSTANCE.getImgDirectory(App.Companion.getCONTEXT()) + "temp_1st_gif.jpg";
File targetFile = new File(targetPath);
while (imageIterator.hasNext()){
GifImage next = imageIterator.next();
if (next != null){
Bitmap bitmap = next.bitmap;
String result = compressBitmap(bitmap, targetPath, App.Companion.getCONTEXT());
bitmap.recycle();
return result;
}
}
return null;
// return targetFile.getAbsolutePath();
} catch (Exception e){
e.printStackTrace();
return null;
} finally {
if (imageIterator != null){
imageIterator.close();
}
}
}
Hi, waynejo, could you add license to your project please, thanks
Hi,
The decodeBitmapData() function will assign values to arrays prefix and suffix according to the data_size field read by dataBlock->read(), the size of these two arrays is 4096, and the value range of data_size field is 0-255, so it may cause the arrays to be out of bounds (for example, some maliciously constructed gif files ).
I noticed that the code comments also mention the problem, but there seems to be no further checks and limits on the array range?
Thanks.
I try to encode some video frame to gif,but when i try add frame bitmap,it's crash and no log.
here it's my sample code:
for (long i = startTime; i < endTime; i += fps) {
Bitmap frameAtTime = null;
long curTime = i * 1000;
if (width > 0 && height > 0) {
frameAtTime = ffmpeg.getScaledFrameAtTime(curTime, MediaMetadataRetrieverCompat.OPTION_CLOSEST, width, height, 90);
} else {
frameAtTime = ffmpeg.getFrameAtTime(curTime, MediaMetadataRetrieverCompat.OPTION_CLOSEST);
}
Log.d(TAG, "Bitmap: " + frameAtTime.getByteCount());
// Bitmap is MUST ARGB_8888.
gifEncoder.encodeFrame(frameAtTime.copy(Bitmap.Config.ARGB_8888, true), delay);
}
I compress bitmap before addframe, but it's unuseful
Should I really re-create the GifDecoder, making it re-load the GIF file after it finishes ?
It probably will take a lot more memory this way.
What's the best way to overcome it?
This error does not occur on debug builds and only first showed up when released to Play. Could it be obfuscation or my proguard rules causing this?
#00 pc 0000000000069cc8 /system/lib64/libc.so (tgkill+8)
#01 pc 000000000001ddd0 /system/lib64/libc.so (abort+88)
#02 pc 00000000004364ec /system/lib64/libart.so (_ZN3art7Runtime5AbortEPKc+528)
#03 pc 0000000000436bfc /system/lib64/libart.so (_ZN3art7Runtime7AborterEPKc+24)
#04 pc 000000000052123c /system/lib64/libart.so (_ZN7android4base10LogMessageD1Ev+900)
#05 pc 00000000002d5230 /system/lib64/libart.so (_ZN3art9JavaVMExt8JniAbortEPKcS2_+1716)
#06 pc 00000000002d54fc /system/lib64/libart.so (_ZN3art9JavaVMExt9JniAbortFEPKcS2_z+176)
#07 pc 00000000003189f8 /system/lib64/libart.so (_ZN3art3JNI11GetMethodIDEP7_JNIEnvP7_jclassPKcS6_+1380)
#08 pc 0000000000012d20 /data/app/com.myapp.android-EHa27T444XHgE6fyFywGRQ==/lib/arm64/libandroidndkgif.so (Java_com_waynejo_androidndkgif_GifDecoder_nativeBitmapIteratornext+424)
#09 pc 000000000035325c /data/app/com.myapp.android-EHa27T444XHgE6fyFywGRQ==/oat/arm64/base.odex
I'm getting
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/system/framework/xxxxxxx.apk", zip file "/data/app/xxxxxx/xxxxxx.apk"],nativeLibraryDirectories=[/data/app/xxxxxxx/lib/arm64, /system/lib64, /vendor/lib64]]] couldn't find "libandroidndkgif.so"
I have
implementation 'com.waynejo:androidndkgif:0.3.3'
on my app build.gradle
I am trying to merge two GIFs. Instead of going through each frame, Is there is any way to merge in a simple way?
If you have a clear picture of each frame, and then generate GIF by GifEncoder class, you will see the transparent region of the current frame of the back of the picture content.
I am getting the error - The size specified at initialization differs from the size of the image.
expected:(425, 450) actual:(850,900).
Below is the code and both input images (p1,p2) have same size(425,450).
int delayMs=100;
GifEncoder gifEncoder = new GifEncoder();
gifEncoder.init(425, 450, dabsolutePath, GifEncoder.EncodingType.ENCODING_TYPE_NORMAL_LOW_MEMORY);
Bitmap bitmap1,bitmap2;
bitmap1= BitmapFactory.decodeResource(getResources(),R.drawable.p1);
bitmap2= BitmapFactory.decodeResource(getResources(),R.drawable.p2);
gifEncoder.encodeFrame(bitmap1, delayMs);
gifEncoder.encodeFrame(bitmap2, delayMs);
gifEncoder.close();
when i encode first frame got error.
A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0xf0f65a68 in tid 28019 (Thread-10404)
If the release is called twice then the
if (NULL != lastColorReducedPixels) {
delete[] lastColorReducedPixels;
lastPixels = NULL;
}
will delete lastColorReducedPixels twice - the second time on null pointer;
void SimpleGCTGifEncoder::release() {
if (NULL != lastPixels) {
delete[] lastPixels;
lastPixels = NULL;
}
if (NULL != lastColorReducedPixels) {
delete[] lastColorReducedPixels;
lastPixels = NULL;
}
if (NULL != fp) {
uint8_t gifFileTerminator = 0x3B;
fwrite(&gifFileTerminator, 1, 1, fp);
fclose(fp);
fp = NULL;
}
}
When I try to encode a gif I get this error:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/ro.markosoft.gifrecorder-1/base.apk"],nativeLibraryDirectories=[/data/app/ro.markosoft.gifrecorder-1/lib/arm64, /data/app/ro.markosoft.gifrecorder-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]] couldn't find "libandroidndkgif.so"
I'm testing on a Nexus 5x.
This is my build.gradle:
`
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "ro.markosoft.gifrecorder"
minSdkVersion 21
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:21.0.0'
compile 'com.android.support:recyclerview-v7:21.0.0'
compile 'com.facebook.fresco:fresco:0.12.0'
compile('com.waynejo:androidndkgif:0.3.1')
}
`
In my case :some device of Android 7.0 reported a crash by Fabric:
Caused by java.lang.UnsatisfiedLinkError
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/-1/base.apk"],nativeLibraryDirectories=[/data/app/-1/lib/arm, /data/app/**-1/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]] couldn't find "libandroidndkgif.so"
where I called “new GifEncoder()”。And in gradle,I have write this code:
splits {
abi {
enable true
reset()
include 'armeabi-v7a'
universalApk false
}
}
Can you tell me where is wrong and how to fix it ?
Thanks!
i can't import this library to my android project.Can anybody help?
Hope can sync to jcenter,thanks
Suppose I know that the canvas (not necessarily of a View class) that I draw to will be not larger than some resolution.
What can I do on this library, to set that the content will scale accordingly, or at least won't take a huge amount of memory in case the GIF is larger than the target resolution size?
Are there also scale types, like on ImageView ?
ArrayList<Bitmap> bitmps;
bitmps = arrayLists[0];
savedImagePath = null;
String imageFileName = "PixelWallChanger.gif";
File storageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
+ "/GIF_Pixel/");
boolean success = true;
if (!storageDir.exists()) {
success = storageDir.mkdirs();
}
if (success) {
File imageFile = new File(storageDir, imageFileName);
savedImagePath = imageFile.getAbsolutePath();
GifEncoder gifEncoder = new GifEncoder();
try {
gifEncoder.init(bitmps.get(0).getWidth(), bitmps.get(0).getHeight(), savedImagePath, GifEncoder.EncodingType.ENCODING_TYPE_STABLE_HIGH_MEMORY);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
for (Bitmap bitmap : bitmps) {
gifEncoder.encodeFrame(bitmap, 60000);
}
gifEncoder.close();
galleryAddPic(savedImagePath);
}
return savedImagePath;
Hi ,
I am using your library. It' really nice library. But there is one issue I am facing and that is:
iOS can support larger gif with more frames and Android lacks this for now and as there are so many mobiles with different configuration it is not being able to support most of the mobiles.
So I think
GifEncoding is not taking memory around less than 25 MB but GifDecoding is taking hell lot of memory.
It will consume more time but it will be more efficient in terms of memory.
May be this will help us to use more frames. As gif supported by iOS are larger and with far more frames.
Thanks,
Umang Kamboj
In my jni code, I used gif.h to make a animated gif, but it's not supporting transparent pixel. Then use your codes, through supports transparent pixel, the gif has residual image.
I have tried use your code. It working fine but i got same problem when I upload output gif after endcoder into Giphy. I just receive message "Bad Request - Gif invalid or corrupt". I think something wrong on output gif file. Please check this. Thank you too!
Hi,
I use ENCODING_TYPE_STABLE_HIGH_MEMORY type to create my gif. When calling close() method takes around 50 seconds. it is too long.
P/s: My tested device is Galaxy S7.
I am using this library to encode the GIF but after google update. I am unable to encode for Android 11+
Can you please update your library or provide the solution.
Thanks,
ENCODING_TYPE_STABLE_HIGH_MEMORY
to get a high quality image but it doesn't meet my need. Any ways to improve this?setThreadCount
, what is its benefit?Hi! Are transparent gifs not "officially" supported? When I encode bitmaps with transparent pixels, I can see glitches in the resulted gif.
when i use ENCODING_TYPE_STABLE_HIGH_MEMORY type encoder, it takes least time but can not stop normally and generate valid gif
Sometimes after encoding my app crashes at the end (when encoder.close()
is called):
2023-09-16 15:27:48.589 13770-13965 libc my.app.id A FORTIFY: fwrite: null FILE*
2023-09-16 15:27:48.736 13770-13817 RenderInspector my.app.id W DequeueBuffer time out on my.app.id/my.app.id.activities.CameraActivity, count=3, avg=21 ms, max=44 ms.
2023-09-16 15:27:48.945 13770-13965 libc my.app.id A Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 13965 (pool-16-thread-), pid 13770 (.app.id)
2023-09-16 15:27:49.523 14023-14023 DEBUG pid-14023 A Cmdline: my.app.id
2023-09-16 15:27:49.523 14023-14023 DEBUG pid-14023 A pid: 13770, tid: 13965, name: pool-16-thread- >>> my.app.id <<<
2023-09-16 15:27:49.524 14023-14023 DEBUG pid-14023 A #03 pc 0000000000019eb4 /data/app/~~J1EVXNeWwwbMII5rmne23w==/my.app.id-egVwL-amUM-5O0nTU8DDmw==/base.apk!libandroidndkgif.so (SimpleGCTGifEncoder::encodeFrame(unsigned int*, int)+152) (BuildId: 1623855e354ccf7631cc06f66e3ffecb55974bff)
2023-09-16 15:27:49.524 14023-14023 DEBUG pid-14023 A #04 pc 000000000001584c /data/app/~~J1EVXNeWwwbMII5rmne23w==/my.app.id-egVwL-amUM-5O0nTU8DDmw==/base.apk!libandroidndkgif.so (Java_com_waynejo_androidndkgif_GifEncoder_nativeEncodeFrame+152) (BuildId: 1623855e354ccf7631cc06f66e3ffecb55974bff)
2023-09-16 15:27:49.524 14023-14023 DEBUG pid-14023 A #07 pc 00000000004af080 /data/app/~~J1EVXNeWwwbMII5rmne23w==/my.app.id-egVwL-amUM-5O0nTU8DDmw==/base.apk
2023-09-16 15:27:49.524 14023-14023 DEBUG pid-14023 A #09 pc 0000000000002272 /data/data/my.app.id/code_cache/.overlay/base.apk/classes4.dex
Despite this, in most cases the gif file is working, but sometimes it is static, as in this issue #31
What could be the cause of the problem?
implementation 'io.github.waynejo:androidndkgif:1.0.1'
// NOTE: The code has been simplified for ease of reading
class GifEncoder {
private lateinit var encoder: GifEncoder
fun create(){
encoder = GifEncoder()
val storageDir = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
.toString() + "/APP_NAME")
if (!storageDir.exists()) {
storageDir.mkdirs()
}
val imageFileName = "APP_NAME_" + System.currentTimeMillis() + ".gif"
val imageFile = File(storageDir, imageFileName)
val savedImagePath = imageFile.absolutePath
encoder.init(480, 640, savedImagePath, GifEncoder.EncodingType.ENCODING_TYPE_SIMPLE_FAST)
}
fun addFrame(bitmap: Bitmap, delay: Int){
encoder.encodeFrame(bitmap, delay)
}
fun stop(){
encoder.close()
}
}
Memory consumption on average remains at 200 MB, and the CPU load does not exceed 30% on POCO X3 NFC.
Hi,
I tried using the lib but it does not seem to work. I am decoding bitmap from image files using Glide and BitmapFactory methods but nothing seems to work. I am making sure that the bitmap config is ARGB_8888, by passing in Bitmap.Options to BitmapFactory and specifying format explicitly for Glide.
This lib is quite fast and I really hope to use it. Please let me know if you need more info to debug the issue.
-Ankit
i compared two library but ndk-gif was more slower than none-ndk-gif encoder.
is there anything difference?
Is it possible to re-start the BitmapIterator after reaching the end? I want to decode one frame at a time to minimize memory usage, but with the current BitmapIterator I can only loop once.
It is not efficient to read/reload constantly from disk every time reaching the end of the iterator.
PS: Is this repository maintained anymore?
Hi, I used your code, its encoding on oppo and samsung but not on my gionee A1, can you help me with this?
0.3.3 gradle long time ,not result
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.