- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
由于这篇文章,我成功地使用 ndk-build 构建了 libjpeg-turbo: libjpeg-turbo for android
我想在 libjpeg-turbo 的 example.c 中获得一个像 read_JPEG_file 这样的原生函数,以便从 Java 代码调用以将其用于 Android 应用。
有人能给我一个例子吗?如何使用 libjpeg-turbo ndk 内置库为 Java 编写本地方法?
我可以通过加载库
System.loadLibrary("libjpeg");
但接下来呢?该库没有任何可从 Java 调用的 native 方法。
我试图根据 JNI 文档编写一个 JNI c 类,但没有成功。示例代码非常适合学习如何操作。
编辑:
我创建了一个测试类 NativeMethods:
package com.test.app;
public class NativeMethods {
private String filename = null;
static {
System.loadLibrary("jpeg"); // this represents compiled libjpeg-turbo under ndk
}
public NativeMethods(String jpegFilename) {
this.filename = jpegFilename;
}
public native int computeNumberOfDCTS(String filename);
}
然后我用javah生成一个本地方法的C头文件,结果是com_test_app_NativeMethods.h
文件包含:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_test_app_NativeMethods */
#ifndef _Included_com_test_app_NativeMethods
#define _Included_com_test_app_NativeMethods
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_test_app_NativeMethods
* Method: computeNumberOfDCTS
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_test_app_NativeMethods_computeNumberOfDCTS
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
然后我创建了名为 JPEGProcessing.c
的文件,我在其中放置了 native 函数的 c 实现,如下所示:
#include "com_test_app_NativeMethods.h"
//that came from jpeglib example
struct my_error_mgr
{
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
typedef struct my_error_mgr * my_error_ptr;
//routine that will replace the standard error_exit method
static void
my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
JNIEXPORT jint JNICALL Java_com_test_app_NativeMethods_computeNumberOfDCTS
(JNIEnv *env, jobject obj, jstring javaString)
{
jint toReturn = 0;
// struct representing jpeg image
struct jpeg_decompress_struct cinfo;
// struct representing error manager; defined above
struct my_error_mgr jerr;
const char *filename = (*env)->GetStringUTFChars(env, javaString, 0);
FILE * infile;
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return -1;
}
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return -1;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
(void) jpeg_read_header(&cinfo, TRUE);
// declare virtual arrays for DCT coefficients
jvirt_barray_ptr* coeffs_array;
// read DCT coefficients from jpeg
coeffs_array = jpeg_read_coefficients(&cinfo);
// fill virtual arrays.
// ci represents component color
// this cycle prints all dct coefficient of the jpeg in 8x8 blocks
for (int ci = 0; ci < 3; ci++)
{
JBLOCKARRAY buffer_one;
JCOEFPTR blockptr_one;
jpeg_component_info* compptr_one;
compptr_one = cinfo.comp_info + ci;
for (int by = 1; by < (compptr_one->height_in_blocks - 1); by++) // we don't want to use the edges of the images
{
buffer_one = (cinfo.mem->access_virt_barray)((j_common_ptr)&cinfo, coeffs_array[ci], by, (JDIMENSION)1, FALSE);
for (int bx = 1; bx < (compptr_one->width_in_blocks - 1); bx++) // we don't want to use the edges of the images
{
blockptr_one = buffer_one[0][bx];
for (int bi = 1; bi < 64; bi++) // we don't want to use AC
{
toReturn++;
}
}
}
}
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return toReturn;
}
文件 JPEGProcessing.c
和 com_test_app_NativeMethods.h
位于 project/jni/
文件夹中。在同一个 jni 文件夹中,我创建了 Android.mk
文件,并在其中放置了这些行:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JPEGProcessing
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := JPEGProcessing.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_LDLIBS := -lm -llog -landroid
LOCAL_STATIC_LIBRARIES := libjpeg
include $(BUILD_SHARED_LIBRARY)
从我的项目目录运行 ndk-build 后出现了一些错误:
jni/JPEGProcessing.c:7:27: error: field 'pub' has incomplete type
jni/JPEGProcessing.c:8:5: error: unknown type name 'jmp_buf'
jni/JPEGProcessing.c:14:16: error: unknown type name 'j_common_ptr'
jni/JPEGProcessing.c: In function 'Java_com_test_app_NativeMethods_computeNumberOfDCTS':
jni/JPEGProcessing.c:30:36: error: storage size of 'cinfo' isn't known
jni/JPEGProcessing.c:36:5: error: unknown type name 'FILE'
jni/JPEGProcessing.c:38:17: error: assignment makes pointer from integer without a cast [-Werror]
jni/JPEGProcessing.c:38:45: error: 'NULL' undeclared (first use in this function)
...
我不明白。如何将代码与 libjpeg-turbo 函数结合起来以获得工作库并在 java 中使用它?
我阅读了 NDK 说明和示例,但仍然不明白。
编辑:
带有简单 native 方法的 NDK 和 JNI 工作得很好。作为测试,我使用了以下效果很好的简单方法:
#include "com_test_app_NativeMethods.h"
JNIEXPORT jint JNICALL Java_com_test_app_NativeMethods_computeNumberOfDCTS
(JNIEnv *env, jobject obj, jstring javaString)
{
jint toReturn = 0;
const char *filename = (*env)->GetStringUTFChars(env, javaString, 0);
const char *test = "test";
if ( filename == test )
{
toReturn++;
}
return toReturn;
}
我用 libjpeg-turbo 试了一下,如下所示:
#include "com_test_app_NativeMethods.h"
#include <stdio.h>
#include <setjmp.h>
#include <libjpeg-turbo/jpeglib.h>
#include <libjpeg-turbo/turbojpeg.h>
#include <libjpeg-turbo/jconfig.h>
#include <libjpeg-turbo/jmorecfg.h>
#include <libjpeg-turbo/jerror.h>
//that came from jpeglib example
struct my_error_mgr
{
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
typedef struct my_error_mgr * my_error_ptr;
//routine that will replace the standard error_exit method
static void
my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
JNIEXPORT jint JNICALL Java_com_test_app_NativeMethods_computeNumberOfDCTS
(JNIEnv *env, jobject obj, jstring javaString)
{
jint toReturn = 0;
// struct representing jpeg image
struct jpeg_decompress_struct cinfo;
// struct representing error manager; defined above
struct my_error_mgr jerr;
const char *filename = (*env)->GetStringUTFChars(env, javaString, 0);
FILE * infile;
if ((infile = fopen(filename, "rb")) == NULL) {
// cannot open file
return -1;
}
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return -1;
}
jpeg_create_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return toReturn;
}
我得到了错误...:
Compile thumb : JPEGProcessing <= JPEGProcessing.c
SharedLibrary : libJPEGProcessing.so
/usr/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/JPEGProcessing/JPEGProcessing.o: in function Java_com_test_app_NativeMethods_computeNumberOfDCTS:jni/JPEGProcessing.c:50: error: undefined reference to 'jpeg_std_error'
/usr/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/JPEGProcessing/JPEGProcessing.o: in function Java_com_test_app_NativeMethods_computeNumberOfDCTS:jni/JPEGProcessing.c:59: error: undefined reference to 'jpeg_CreateDecompress'
/usr/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/JPEGProcessing/JPEGProcessing.o: in function Java_com_test_app_NativeMethods_computeNumberOfDCTS:jni/JPEGProcessing.c:61: error: undefined reference to 'jpeg_destroy_decompress'
/usr/android-ndk-r8c/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/JPEGProcessing/JPEGProcessing.o: in function Java_com_test_app_NativeMethods_computeNumberOfDCTS:jni/JPEGProcessing.c:54: error: undefined reference to 'jpeg_destroy_decompress'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libJPEGProcessing.so] Error 1
那么如何将原生代码与 ndk 构建的 libjpeg-turbo 库一起使用呢?
最佳答案
由于 libjpeg_turbo 被编译为 C 库,而您的 Android native 代码被编译为 C++ 程序,因此您应该通过链接指令包含 C 库。
试试这个,
extern "C" {
#include "headers of libjpeg_turbo"
}
关于java - Android 如何通过 JNi 示例使用 libjpeg-turbo 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14325639/
我的目的是使用 libjpeg-turbo (参见 http://www.libjpeg-turbo.org/Main/HomePage )作为独立 Jpeg Group ( http://www.i
当使用 libjpeg 将图像输入 OpenCL 时,为了能够将 channel 视为具有 CL_UNORM_INT8(在 [0.0, 1.0] 范围内 float )的规范化 uint8,您只能用
在我的 C 程序中,我想使用 libexif 和 libjpeg 在给定路径 inputFilePath,并将生成的 jpeg 保存到输出路径 outputFilePath。 输入的 jpeg 文件很
如标题所示,我使用 AWS EC2 和 AWS linux AMI 来设置运行神经式算法的环境。 Nerual-style 我已经成功安装了 torch、Lua、Loadcaffe、Google Pr
如果可能的话,我想使用 libjpeg 从 JPEG 图像的中间读取一行而不读取前面的所有行。这能做到吗? 最佳答案 答案几乎肯定是“是的,你可以,但它需要比你想要的更多的努力”。 JPEG 图像是标
我想使用 libjpeg 库将图像保存到内存( vector )中。我发现那里有功能: init_destination empty_output_buffer term_destination 我的
我正在使用 libjpeg 解码 jpeg 文件。在解码大图像时,用户可能会切换到另一个 jpeg 文件,那么 libjpeg 是否支持解码中断?非常感谢! 最佳答案 Libjpeg 有一个 I/O
我大部分时间都在使用该示例,它确实创建了一个只是乱码的图像: unsigned char* readJpeg(JNIEnv* env, libraw_processed_image_t *raw) {
我使用来自 Independent JPEG Group 的 jpeg 库 v8d我想改变 jpeg 解压缩读取和处理数据的方式。 在 djpeg main() 中,在每个 jpeg_read_sca
来自 jmorecfg.h : #define PACK_TWO_PIXELS(l,r) ((r>16; \ } while(0) #define WRITE_TWO_ALIGNED
我无法理解我从以下代码中得到的段错误: #include #include #include int main(int argc, char** argv){ FILE*
我正在尝试使用 ijg 的 libjpeg 将 RGB 图像压缩为 JPEG。最后的想法是使用图像传感器拍摄图像并将数据压缩为 ARM Cortex M3 Controller 上的 JPEG;但是,
所以我一直在阅读 libjpeg 文档,它非常乏善可陈。 我一直在尝试弄清楚如何从自定义内存缓冲区而不是文件中读取数据,但我不确定如何测试我的解决方案是否正常工作。 目前我从内存中加载 jpeg 的函
我有下一个基于 libjpeg 的 JPEG 图像解压缩标准代码。 jpeg_decompress_struct cinfo; // ...Set error manager and data sou
我正在尝试使用mingw-w64编译libjpeg(版本8d)。我启动的命令是: MyS.BAT /配置 制作 在第三步,我得到这个错误: $ make D:/Builder/bin/make al
我有这样一个常用的代码: struct jpeg_decompress_struct cinfo; jpeg_create_decompress(&cinfo); jpeg_stdio_src(&ci
我正在尝试使用 libjpeg 将图像从一个文件复制到另一个文件。我尝试使用 jpeg_read_scanlines/jpeg_write_scanlines 来复制图像数据,但据我所知这些函数计算
我已经创建了自己的 DCT 计算。 如何使用 jpeg_write_coefficients 将我的 64 个 DCT 值写入使用 jpeg_write_coefficients 的 JPEG 文件(
libjpeg 是否允许/具有缩放输出图像的例程? 我有一个图像需要在保存和加载时调整大小,在输入上提供 width1、height1 并在输出上获取 width2、height2,我真的不能在外面使
我正在使用 C++ JPEG 库 (libjpeg),我意识到当某些函数失败时会调用 exit() 并关闭应用程序。如何覆盖此行为并防止应用程序因 libjpeg 错误而关闭? 最佳答案 这是 lib
我是一名优秀的程序员,十分优秀!