我终于成功地建立的libjpeg涡轮增压静态库感谢这个 的libjpeg涡轮增压为Android 现在我有一个libjpeg.a和NDK建造产生的libsimd.a
i finally managed to build libjpeg-turbo static library thanks to this libjpeg-turbo for android now i have a libjpeg.a and a libsimd.a generated by ndk-build
但我一直没能找到有关下一步该怎么做的任何信息?我是从一个缓冲区(从插座)德codeA JPEG使用生成位图中BitmapFactory其正常工作
but i have not been able to find any info about what to do next? i'm decode a jpeg from a buffer (from a socket) to a bitmap using the build in BitmapFactory which works fine
byte[] jpgBits = new byte[jpgBitsLen];
dis.readFully(jpgBits);
Bitmap bmp = BitmapFactory.decodeByteArray(jpgBits, 0, jpgBitsLen);
我如何使用的libjpeg涡轮增压替代BitmapFactory.de codeByteArray?
how do i replace BitmapFactory.decodeByteArray with libjpeg-turbo?
我的连接code。使用本我的PC上的流
i encode the stream on my PC using this
tjhandle rmfdJpegCompressor = tjInitCompress();
tjCompress2(rmfdJpegCompressor, (unsigned char *)s_rmfdPixels, MFD_WH, 0, MFD_WH, TJPF_BGRX,
&rmfdBits, &rmfdBitsLen, TJSAMP_420, RMFD_JPEG_QUALITY,
0);
tjDestroy(rmfdJpegCompressor);
这工作得很好,所以我认为必须有一个Android等价?
which work fine, so i think there must be an android equivalent?
我读到这 https://wiki.linaro.org/BenjaminGaignard/libjpeg-turboAndSkia 这是否意味着使用它是重建的Android源,以便它使用的libjpeg涡轮增压的唯一途径?我读的地方有一个兼容的API和本地的API的libjpeg涡轮增压,我很高兴使用任何API是最简单的,因为我不喜欢改造的Android
i read this https://wiki.linaro.org/BenjaminGaignard/libjpeg-turboAndSkia does this mean the only way to use it is to rebuild android sources so it uses libjpeg-turbo? i read somewhere there is a compatibility api and a native api for libjpeg-turbo and i'm happy to use whatever api is easiest since i don't fancy rebuilding android
我已经尝试了以下内容: 在我的项目的根我创建的文件夹JNI /包括,把turbojpeg.h在那里 在我的项目的根我创建的文件夹JNI / prebuilt并把libjpeg.a在那里
i've tried the following: under my project root i created folders jni/include and put turbojpeg.h in there under my project root i created folders jni/prebuilt and put libjpeg.a in there
在我的Java code,我把
in my java code, i put
private native int tjInitDecompress();
在MainActivity 而在我的onCreate添加
in MainActivity and in onCreate i add
int i = tjInitDecompress();
Log.d("MainActivity", "i="+i);
它建立和运行,但崩溃在tjInitDecom preSS
it builds and runs but crashes at tjInitDecompress
在日志中这样说的: 没有找到实现原生LCOM / example.jpegtest / MainActivity; .tjInitDecom preSS()我
in the log it says: No implementation found for native Lcom/example.jpegtest/MainActivity;.tjInitDecompress ()I
感谢
那么,它是工作的山,但我终于得到了一些工作,所以我不想让任何人谁是有兴趣知道我是怎么做的。
well, its been a mountain of work but i finally got something working so i want to let anyone who's interested know how i did it.
首先我建立了招呼进演示如下描述 https://developer.android.com/tools/sdk/ndk/index.html
first i built the hello-jin demo as described here https://developer.android.com/tools/sdk/ndk/index.html
然后我创建了一个新的项目,复制的JNI和改变的C FUNC的名字,以匹配新的包和类名。不使用 - 和_在你的包的名字,或者你会出现问题。只是,x0-9是最好的。
then i created a new project, copied the jni and changed the names of the c func to match the new package and class name. don't use - and _ in your package name or you will have problems. just a-x0-9 is best.
然后我复制所有的libjpeg涡轮增压文件,并显示目录到JNI和测试的NDK建造仍然工作
then i copied all the libjpeg-turbo file and dirs into jni and tested that ndk-build still worked
然后我创建了一个JNI包装的libjpg玩意儿像这样 tjpegini-arm.c
then i created a jni wrapper for the libjpg funs like this tjpegini-arm.c
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <jni.h>
#include "turbojpeg.h"
/*
* Class: libjpegturbo_jniapi
* Method: tjInitDecompress
* Signature: ()I
*/
//package com.design2112.fbmslpit
//public class MainActivity
jint JNICALL Java_com_design2112_fbmslpit_MainActivity_tjInitDecompress
(JNIEnv *env, jobject thisObj)
{
return (int)tjInitDecompress();
}
/*
* Class: libjpegturbo_jniapi
* Method: tjDecompressHeader2
* Signature: (I[BI)I
*/
jint JNICALL Java_com_design2112_fbmslpit_MainActivity_tjDecompressHeader2
(JNIEnv *env, jobject thisObj, jint handle, jbyteArray jpegBuf, jint jpegSize)
{
jbyte *real_jpegBuf = (*env)->GetByteArrayElements(env, jpegBuf, 0);
if (!real_jpegBuf) return -1;
//jsize length = (*env)->GetArrayLength(env, real_jpegBuf);
/*for (i = 0; i < length; i++) {
sum += inCArray[i];
}*/
int width, height, jpegSubsamp;
int ret = tjDecompressHeader2((tjhandle)handle,
(unsigned char *)real_jpegBuf, (unsigned long)jpegSize, &width, &height,
&jpegSubsamp);
if(ret!=0) {
return 0;
}
// ok, so pack width and height together
return width<<16 | height;
}
/*
* Class: libjpegturbo_jniapi
* Method: tjDecompress2
* Signature: (I[BI[IIIIII)V
*/
void JNICALL Java_com_design2112_fbmslpit_MainActivity_tjDecompress2
(JNIEnv *env, jobject thisObj, jint handle, jbyteArray jpegBuf, jint jpegSize, jintArray dstBuf,
jint width, jint pitch, jint height, jint pixelFormat, jint flags)
{
jbyte *real_jpegBuf = (*env)->GetByteArrayElements(env, jpegBuf, 0);
if (!real_jpegBuf) return;
jint *real_dstBuf = (*env)->GetIntArrayElements(env, dstBuf, 0);
if (!real_dstBuf) return;
jsize length = (*env)->GetArrayLength(env, jpegBuf);
tjDecompress2((tjhandle)handle,
(unsigned char *)real_jpegBuf, (unsigned long)jpegSize, (unsigned char *)real_dstBuf,
width, pitch, height, pixelFormat, flags);
}
/*
* Class: libjpegturbo_jniapi
* Method: tjDestroy
* Signature: (I)V
*/
void JNICALL Java_com_design2112_fbmslpit_MainActivity_tjDestroy
(JNIEnv *env, jobject thisObj, jint handle)
{
tjDestroy((tjhandle)handle);
}
重要的是,你将不得不重新命名com_design2112_fbmslpit_MainActivity你的包和类这个工作
IMPORTANT, you will have to rename com_design2112_fbmslpit_MainActivity to your package and class for this to work
添加tjpegini-arm.c到Android.mk makefile文件,然后运行NDK建造的JNI DIR
add tjpegini-arm.c to the Android.mk makefile then run ndk-build in the jni dir
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk obj/local/armeabi/libjpeg.so LOCAL_ARM_MODE=arm
和的。所以复制到正确的名称和地点
and copy the .so to the right name and place
cp obj/local/armeabi/libjpeg.so ../libs/armeabi/libtjpegjni-arm.so
然后在我的MainAvtivity.java
then in my MainAvtivity.java
public class MainActivity extends Activity {
public native int tjInitDecompress();
public native int tjDecompressHeader2(int handle, byte[] jpegBits, int jpegBitsLen);
public native void tjDecompress2(int handle, byte[] jpegBits,
int jpegBitsLen, int[] outbuffer, int width, int pitch, int height,
int pixelFormat, int flags);
public native void tjDestroy(int handle);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
File sdcard = Environment.getExternalStorageDirectory();
//Get the text file
File file = new File(sdcard,"/Download/test.jpg");
int jpegBitsLen = (int) file.length();
byte[] jpegBits = new byte[jpegBitsLen];
DataInputStream dis;
try {
dis = new DataInputStream(new FileInputStream(file));
dis.readFully(jpegBits);
dis.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.loadLibrary("tjpegjni-arm");
int jpegDec = tjInitDecompress();
int wh = tjDecompressHeader2(jpegDec, jpegBits, jpegBitsLen);
int width = wh>>16;
int height = wh&0x7fff;
int[] buffer = new int[width*height];
tjDecompress2(jpegDec, jpegBits, jpegBitsLen, buffer, width, 0/*pitch*/, height, 2 /*TJPF_RGBX*/, 0);
tjDestroy(jpegDec);
Bitmap bmp = Bitmap.createBitmap(buffer, width, height, Bitmap.Config.ARGB_8888);
}
这基本上它。可以显示BMP,你想要的任何方式。
that's basically it. you can display the bmp any way you want.
工作的这一点我狗屎负荷找出无JNI NDK的经验都没有。如果有人认为这有用的,发邮件给我一杯啤酒。
this too me a shit load of work to figure out having no jni ndk experience at all. if someone finds this usefull, email me a beer.
更新,这里的令人震惊的消息,其采取20ms的脱codeA 450x450的图像。 内置的BitmapFactory.de codeByteArray做它在大约相同的!
UPDATE, here's the shocking news, its taking 20ms to decode a 450x450 image. the built in BitmapFactory.decodeByteArray does it in about the same!
如果任何人试图这一点,并得到不同的结果,请记
if anyone else tries this and gets different results, please make a note
上一篇:是否有可能重写了IEnumerable在VC ++ / CLI?有可能、写了、IEnumerable、VC
下一篇:反序列化的base64 EN codeD字节数组返回不同的结果在2 JSON.net库版本数组、字节、不同、版本