Android中Gif播放
来源:互联网 发布:windows连不上aws 编辑:程序博客网 时间:2024/05/21 18:44
DEMO地址:https://github.com/zhaopingfu/GifPlayerDemo
Gif 格式图片详细解析:http://blog.csdn.net/wzy198852/article/details/17266507
Android中Gif播放一般有三种方式
自定义View
这里用了一个开源库提供的自定义gifview https://code.google.com/archive/p/gifview/downloads
NDK方式
这里以android-gif-drawable为例,但是不是用的这个库,是用的系统的代码
系统代码在\android-6.0.0_r1\external\giflib中
先将gif放在外置卡的根目录下
final File file = newFile(Environment.getExternalStorageDirectory(), “demo.gif”);
还需要自己写一些 #include <jni.h> #include <string> #include "gif_lib.h" #include <android/log.h> #include <android/bitmap.h> #include <malloc.h> #define LOG_TAG "pf" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define argb(a, r, g, b)(((a) & 0xff) << 24) | ((r) & 0xff)| (((g) & 0xff) << 8)| (((b) & 0xff) << 16) typedef struct GifBean { int current_frame; int total_frame; int *delayed; } GifBean; extern "C" { JNIEXPORT jlong JNICALL Java_com_pf_gifplayerdemo_ndk_GifHandler_loadPath(JNIEnv *env, jobject instance, jstring path_) { const char *path = env->GetStringUTFChars(path_, NULL); int err; //用系统函数打开一个gif文件,返回一个结构体,这个结构体为句柄 GifFileType *gifFileType = DGifOpenFileName(path, &err); DGifSlurp(gifFileType); //封装成自己想要的 GifBean *gifBean = (GifBean *) malloc(sizeof(struct GifBean)); //清空内存地址 memset(gifBean, 0, sizeof(struct GifBean)); //相当于view.setTag gifFileType->UserData = gifBean; gifBean->delayed = (int *) malloc(sizeof(int) * gifFileType->ImageCount); memset(gifBean->delayed, 0, (sizeof(int) * gifFileType->ImageCount)); gifBean->total_frame = gifFileType->ImageCount; ExtensionBlock *ext; int i, j; for (i = 0; i < gifFileType->ImageCount; i++) { SavedImage frame = gifFileType->SavedImages[i]; for (j = 0; j < frame.ExtensionBlockCount; j++) { if (frame.ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE) { ext = &frame.ExtensionBlocks[j]; break; } } if (ext) { int frame_delay = 10 * (ext->Bytes[2] << 8 | ext->Bytes[1]); LOGE("时间:%d", frame_delay); gifBean->delayed[i] = frame_delay; } } LOGE("gif长度大小:%d", gifFileType->ImageCount); env->ReleaseStringUTFChars(path_, path); return (jlong) gifFileType; } JNIEXPORT jint JNICALL Java_com_pf_gifplayerdemo_ndk_GifHandler_getWidth(JNIEnv *env, jobject instance, jlong ndkGif) { return ((GifFileType *) ndkGif)->SWidth; } JNIEXPORT jint JNICALL Java_com_pf_gifplayerdemo_ndk_GifHandler_getHeight(JNIEnv *env, jobject instance, jlong ndkGif) { return ((GifFileType *) ndkGif)->SHeight; } //绘制一张图片 void drawFrame(GifFileType *gifFileType, GifBean *gifBean, AndroidBitmapInfo androidBitmapInfo, void *pixels) { //拿到当前帧 SavedImage savedImage = gifFileType->SavedImages[gifBean->current_frame]; GifImageDesc gifImageDesc = savedImage.ImageDesc; //整幅图片的首地址 int *px = (int *) pixels; //每一行的首地址 int *line; //其中一个像素的位置,不是指针,在颜色表中的索引 int pointPixel; GifByteType gifByteType; GifColorType gifColorType; ColorMapObject *colorMapObject = gifImageDesc.ColorMap; px = (int *) ((char *) px + androidBitmapInfo.stride * gifImageDesc.Top); int x, y; for (y = gifImageDesc.Top; y < gifImageDesc.Top + gifImageDesc.Height; ++y) { line = px; for (x = gifImageDesc.Left; x < gifImageDesc.Left + gifImageDesc.Width; ++x) { pointPixel = (y - gifImageDesc.Top) * gifImageDesc.Width + (x - gifImageDesc.Left); gifByteType = savedImage.RasterBits[pointPixel]; gifColorType = colorMapObject->Colors[gifByteType]; line[x] = argb(255, gifColorType.Red, gifColorType.Green, gifColorType.Blue); } px = (int *) ((char *) px + androidBitmapInfo.stride); } } JNIEXPORT jint JNICALL Java_com_pf_gifplayerdemo_ndk_GifHandler_updateFrame(JNIEnv *env, jobject instance, jobject bitmap, jlong ndkGif) { GifFileType *gifFileType = (GifFileType *) ndkGif; GifBean *gifBean = (GifBean *) gifFileType->UserData; AndroidBitmapInfo androidBitmapInfo; //代表一幅图片的像素数组 void *pixels; AndroidBitmap_getInfo(env, bitmap, &androidBitmapInfo); //锁定bitmap 一幅图片->二维数组 AndroidBitmap_lockPixels(env, bitmap, &pixels); //TODO drawFrame(gifFileType, gifBean, androidBitmapInfo, pixels); //播放完之后,循环到下一帧 gifBean->current_frame += 1; LOGE("当前帧:%d", gifBean->current_frame); if (gifBean->current_frame >= gifBean->total_frame - 1) { gifBean->current_frame = 0; LOGE("重新来过,当前帧:%d", gifBean->current_frame); } AndroidBitmap_unlockPixels(env, bitmap); return gifBean->delayed[gifBean->current_frame]; } }
WebView方式
直接将gif放在assets路径下 webview = (WebView) findViewById(R.id.webview); String url = "file:///android_asset/demo.gif"; WebSettings webSettings = webview.getSettings(); webSettings.setJavaScriptEnabled(true); // User settings webSettings.setJavaScriptEnabled(true); webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setUseWideViewPort(true);//关键点 webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); webSettings.setDisplayZoomControls(false); webSettings.setJavaScriptEnabled(true); // 设置支持javascript脚本 webSettings.setAllowFileAccess(true); // 允许访问文件 webSettings.setBuiltInZoomControls(true); // 设置显示缩放按钮 webSettings.setSupportZoom(true); // 支持缩放 webSettings.setLoadWithOverviewMode(true); DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int mDensity = metrics.densityDpi; Log.d("maomao", "densityDpi = " + mDensity); if (mDensity == 240) { webSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR); } else if (mDensity == 160) { webSettings.setDefaultZoom(WebSettings.ZoomDensity.MEDIUM); } else if(mDensity == 120) { webSettings.setDefaultZoom(WebSettings.ZoomDensity.CLOSE); }else if(mDensity == DisplayMetrics.DENSITY_XHIGH){ webSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR); }else if (mDensity == DisplayMetrics.DENSITY_TV){ webSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR); }else{ webSettings.setDefaultZoom(WebSettings.ZoomDensity.MEDIUM); } /** * 用WebView显示图片,可使用这个参数 设置网页布局类型: * 1、LayoutAlgorithm.NARROW_COLUMNS 适应内容大小 * 2、LayoutAlgorithm.SINGLE_COLUMN:适应屏幕,内容将自动缩放 */ //webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); webview.loadUrl(url);
阅读全文
0 0
- Android中Gif播放
- Android中播放GIF动画
- Android中播放GIF图片动画
- Android中播放GIF图片动画
- android中播放gif动画之一
- android中播放gif动画之二
- android中播放gif动画之三
- 如何在android中播放gif动画
- Android中播放Gif图片的方法
- Android中播放Gif图片的方法
- android 实现gif播放
- Android播放gif动画
- Android 播放Gif 动画
- Android播放Gif动画
- Android 播放Gif 动画
- Android 播放Gif 动画
- Android播放GIF图片
- Android播放GIF动画
- Python 生成随机字符串
- MySQL的视图
- 初识Spring
- AlexNet-ImageNet Classification with Deep Convolutional Neural Networks
- 设计模式系列之「代理模式」
- Android中Gif播放
- Python之旧式类、新式类(关键词:Python/旧式类/经典类/新式类)
- Java反射——Class Loader
- linux hadoop 安装
- 几行代码搞定python破解mysql数据库【二】
- Android实现的写字板(绘画板)
- Query Mobile学习笔记(七)——主题与打包
- 智能性爱机器人的“黑暗面”:伴侣也会变杀手
- Java的多线程