我正在使用(https://github.com/cats-oss/android-gpuimage)这个库创建一个抠像相机应用程序。我从这里下载文件,并将其包含在我的项目中。该项目正确编译,但运行后会引发此错误
未找到空jp.co.cyberagent.android.gpuimage.GPUImageNativeLibrary.YUVtoRBGA(byte [],int,int,int [])的实现(尝试Java_jp_co_cyberagent_android_gpuimage_GPUImageNativeLibrary_YUVtoRBGA和Java_jp_Co_cy_cytoative_3 E / AndroidRuntime:致命例外:GLThread 15199 流程:com.youthbuzz.chromakeyapp,PID:13306 java.lang.UnsatisfiedLinkError:未找到针对无效jp.co.cyberagent.android.gpuimage.GPUImageNativeLibrary.YUVtoRBGA(byte [],int,int,int [])的实现(已尝试Java_jp_co_cyberagent_android_gpuimage_GPUImagenativeLibrary_Y_UV_RB_______________3__ 在jp.co.cyberagent.android.gpuimage.GPUImageNativeLibrary.YUVtoRBGA(本机方法) 在jp.co.cyberagent.android.gpuimage.GPUImageRenderer $ 1.run(GPUImageRenderer.java:122) 在jp.co.cyberagent.android.gpuimage.GPUImageRenderer.runAll(GPUImageRenderer.java:107) 在jp.co.cyberagent.android.gpuimage.GPUImageRenderer.onDrawFrame(GPUImageRenderer.java:90) 在android.opengl.GLSurfaceView $ GLThread.guardedRun(GLSurfaceView.java:1575) 在android.opengl.GLSurfaceView $ GLThread.run(GLSurfaceView.java:1270)
这是错误中提到的课程。
public class GPUImageRenderer implements Renderer, PreviewCallback {
public static final int NO_IMAGE = -1;
static final float[] CUBE = new float[]{-1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f, 1.0f};
public static Runnable SAVED_CALLBACK = null;
public static boolean SAVE_TO_BITMAP = false;
public static Bitmap image = null;
public final Object mSurfaceChangedWaiter = new Object();
private final FloatBuffer mGLCubeBuffer;
private final FloatBuffer mGLTextureBuffer;
private final Queue<Runnable> mRunOnDraw;
private final Queue<Runnable> mRunOnDrawEnd;
GPUImageCallback callback;
GPUImageNativeLibrary gpuImageNativeLibrary;
private int mAddedPadding;
private float mBackgroundBlue = 0.0f;
private float mBackgroundGreen = 0.0f;
private float mBackgroundRed = 0.0f;
private GPUImageFilter mFilter;
private boolean mFlipHorizontal;
private boolean mFlipVertical;
private IntBuffer mGLRgbBuffer;
private int mGLTextureId = -1;
private int mImageHeight;
private int mImageWidth;
private int mOutputHeight;
private int mOutputWidth;
private Rotation mRotation;
private ScaleType mScaleType = ScaleType.CENTER_CROP;
private SurfaceTexture mSurfaceTexture = null;
public GPUImageRenderer(GPUImageFilter filter) {
this.mFilter = filter;
this.mRunOnDraw = new LinkedList();
this.mRunOnDrawEnd = new LinkedList();
gpuImageNativeLibrary=new GPUImageNativeLibrary();
this.mGLCubeBuffer = ByteBuffer.allocateDirect(CUBE.length *
4).order(ByteOrder.nativeOrder()).asFloatBuffer();
this.mGLCubeBuffer.put(CUBE).position(0);
this.mGLTextureBuffer =
ByteBuffer.allocateDirect(TextureRotationUtil.TEXTURE_NO_ROTATION.length *
4).order(ByteOrder.nativeOrder()).asFloatBuffer();
setRotation(Rotation.NORMAL, false, false);
}
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES30.glClearColor(this.mBackgroundRed, this.mBackgroundGreen,
this.mBackgroundBlue, 1.0f);
GLES30.glDisable(GLES20.GL_DEPTH_TEST);
this.mFilter.init();
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
this.mOutputWidth = width;
this.mOutputHeight = height;
GLES30.glViewport(0, 0, width, height);
GLES30.glUseProgram(this.mFilter.getProgram());
this.mFilter.onOutputSizeChanged(width, height);
adjustImageScaling();
synchronized (this.mSurfaceChangedWaiter) {
this.mSurfaceChangedWaiter.notifyAll();
}
}
public void onDrawFrame(GL10 gl) {
GLES30.glClear(GLES20.GL_COLOR_BUFFER_BIT |
GLES20.GL_DEPTH_BUFFER_BIT);
runAll(this.mRunOnDraw);
this.mFilter.onDraw(this.mGLTextureId, this.mGLCubeBuffer,
this.mGLTextureBuffer);
runAll(this.mRunOnDrawEnd);
if (this.mSurfaceTexture != null) {
this.mSurfaceTexture.updateTexImage();
}
}
public void setBackgroundColor(float red, float green, float blue) {
this.mBackgroundRed = red;
this.mBackgroundGreen = green;
this.mBackgroundBlue = blue;
}
private void runAll(Queue<Runnable> queue) {
synchronized (queue) {
while (!queue.isEmpty()) {
((Runnable) queue.poll()).run();
}
}
}
public void onPreviewFrame(final byte[] data, final Camera camera) {
try {
if (camera.getParameters() != null) {
final Size previewSize =
camera.getParameters().getPreviewSize();
if (this.mGLRgbBuffer == null) {
this.mGLRgbBuffer =
IntBuffer.allocate(previewSize.width * previewSize.height);
}
if (this.mRunOnDraw.isEmpty()) {
runOnDraw(new Runnable() {
public void run() {
gpuImageNativeLibrary.YUVtoRBGA(data,
previewSize.width, previewSize.height, mGLRgbBuffer.array());
mGLTextureId =
OpenGlUtils.loadTexture(GPUImageRenderer.this.mGLRgbBuffer, previewSize,
GPUImageRenderer.this.mGLTextureId);
camera.addCallbackBuffer(data);
if (mImageWidth != previewSize.width) {
mImageWidth = previewSize.width;
mImageHeight = previewSize.height;
adjustImageScaling();
}
}
});
}
}
} catch (Exception e) {
}
}
public void setUpSurfaceTexture(final Camera camera) {
runOnDraw(new Runnable() {
public void run() {
int[] textures = new int[1];
GLES30.glGenTextures(1, textures, 0);
GPUImageRenderer.this.mSurfaceTexture = new
SurfaceTexture(textures[0]);
try {
camera.setPreviewTexture(GPUImageRenderer.this.mSurfaceTexture);
camera.setPreviewCallback(GPUImageRenderer.this);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public void setFilter(final GPUImageFilter filter) {
runOnDraw(new Runnable() {
public void run() {
GPUImageFilter oldFilter = GPUImageRenderer.this.mFilter;
GPUImageRenderer.this.mFilter = filter;
if (oldFilter != null) {
oldFilter.destroy();
}
GPUImageRenderer.this.mFilter.init();
GLES30.glUseProgram(GPUImageRenderer.this.mFilter.getProgram());
GLES30.glUseProgram(mFilter.getProgram());
GPUImageRenderer.this.mFilter.onOutputSizeChanged
(GPUImageRenderer.this.mOutputWidth, GPUImageRenderer.this.mOutputHeight);
}
});
}
public void deleteImage() {
runOnDraw(new Runnable() {
@Override
public void run() {
GLES30.glDeleteTextures(1, new int[]
{GPUImageRenderer.this.mGLTextureId}, 0);
GPUImageRenderer.this.mGLTextureId = -1;
}
});
}
public void setImageBitmap(Bitmap bitmap) {
setImageBitmap(bitmap, true);
}
public void setImageBitmap(final Bitmap bitmap, final boolean recycle)
{
if (bitmap != null) {
runOnDraw(new Runnable() {
public void run() {
Bitmap resizedBitmap = null;
if (bitmap.getWidth() % 2 == 1) {
resizedBitmap =
Bitmap.createBitmap(bitmap.getWidth() + 1, bitmap.getHeight(),
Config.ARGB_8888);
Canvas can = new Canvas(resizedBitmap);
can.drawARGB(0, 0, 0, 0);
can.drawBitmap(bitmap, 0.0f, 0.0f, null);
GPUImageRenderer.this.mAddedPadding = 1;
} else {
GPUImageRenderer.this.mAddedPadding = 0;
}
GPUImageRenderer.this.mGLTextureId =
OpenGlUtils.loadTexture(resizedBitmap != null ? resizedBitmap : bitmap,
GPUImageRenderer.this.mGLTextureId, recycle);
if (resizedBitmap != null) {
resizedBitmap.recycle();
}
GPUImageRenderer.this.mImageWidth = bitmap.getWidth();
GPUImageRenderer.this.mImageHeight =
bitmap.getHeight();
GPUImageRenderer.this.adjustImageScaling();
}
});
}
}
public void setScaleType(ScaleType scaleType) {
this.mScaleType = scaleType;
}
protected int getFrameWidth() {
return this.mOutputWidth;
}
protected int getFrameHeight() {
return this.mOutputHeight;
}
private void adjustImageScaling() {
float outputWidth = (float) this.mOutputWidth;
float outputHeight = (float) this.mOutputHeight;
if (this.mRotation == Rotation.ROTATION_270 || this.mRotation ==
Rotation.ROTATION_90) {
outputWidth = (float) this.mOutputHeight;
outputHeight = (float) this.mOutputWidth;
}
float ratioMax = Math.max(outputWidth / ((float)
this.mImageWidth), outputHeight / ((float) this.mImageHeight));
int imageWidthNew = Math.round(((float) this.mImageWidth) *
ratioMax);
float ratioWidth = ((float) imageWidthNew) / outputWidth;
float ratioHeight = ((float) Math.round(((float)
this.mImageHeight) * ratioMax)) / outputHeight;
float[] cube = CUBE;
float[] textureCords =
TextureRotationUtil.getRotation(this.mRotation, this.mFlipHorizontal,
this.mFlipVertical);
if (this.mScaleType == ScaleType.FIT_XY) {
float distHorizontal = (1.0f - (1.0f / ratioWidth)) / 2.0f;
float distVertical = (1.0f - (1.0f / ratioHeight)) / 2.0f;
textureCords = new float[]{addDistance(textureCords[0],
distHorizontal), addDistance(textureCords[1], distVertical),
addDistance(textureCords[2], distHorizontal), addDistance(textureCords[3],
distVertical), addDistance(textureCords[4], distHorizontal),
addDistance(textureCords[5], distVertical), addDistance(textureCords[6],
distHorizontal), addDistance(textureCords[7], distVertical)};
} else {
cube = new float[]{CUBE[0] / ratioHeight, CUBE[1] /
ratioWidth, CUBE[2] / ratioHeight, CUBE[3] / ratioWidth, CUBE[4] /
ratioHeight, CUBE[5] / ratioWidth, CUBE[6] / ratioHeight, CUBE[7] /
ratioWidth};
}
this.mGLCubeBuffer.clear();
this.mGLCubeBuffer.put(cube).position(0);
this.mGLTextureBuffer.clear();
this.mGLTextureBuffer.put(textureCords).position(0);
}
private float addDistance(float coordinate, float distance) {
return coordinate == 0.0f ? distance : 1.0f - distance;
}
public void setRotationCamera(Rotation rotation, boolean
flipHorizontal, boolean flipVertical) {
setRotation(rotation, flipHorizontal, flipVertical);
}
public void setRotation(Rotation rotation, boolean flipHorizontal,
boolean flipVertical) {
this.mFlipHorizontal = flipHorizontal;
this.mFlipVertical = flipVertical;
setRotation(rotation);
}
public Rotation getRotation() {
return this.mRotation;
}
public void setRotation(Rotation rotation) {
this.mRotation = rotation;
adjustImageScaling();
}
public boolean isFlippedHorizontally() {
return this.mFlipHorizontal;
}
public boolean isFlippedVertically() {
return this.mFlipVertical;
}
protected void runOnDraw(Runnable runnable) {
synchronized (this.mRunOnDraw) {
this.mRunOnDraw.add(runnable);
}
}
protected void runOnDrawEnd(Runnable runnable) {
synchronized (this.mRunOnDrawEnd) {
this.mRunOnDrawEnd.add(runnable);
}
}
public interface GPUImageCallback {
void callback(Bitmap bitmap);
}
}