如何在不调整原始图像大小的情况下使用GPU
Image库,我需要为整个GPUImageView申请像Pixelate或Blur这样的过滤器.
我想用GPUImage,但我不知道怎么做.
解决方法
您更改GPUImage库GPUImageRendering类
下面的代码是
下面的代码是
/* * Copyright (C) 2012 CyberAgent * * 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. */ package jp.co.cyberagent.android.gpuimage; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.hardware.Camera.PreviewCallback; import android.hardware.Camera.Size; import android.opengl.GLES20; import android.opengl.GLSurfaceView.Renderer; import jp.co.cyberagent.android.gpuimage.util.TextureRotationUtil; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.LinkedList; import java.util.Queue; import static jp.co.cyberagent.android.gpuimage.util.TextureRotationUtil.TEXTURE_NO_ROTATION; @SuppressLint("WrongCall") @TargetApi(11) public class GPUImageRenderer implements Renderer,PreviewCallback { public static final int NO_IMAGE = -1; static final float CUBE[] = { -1.0f,-1.0f,1.0f,}; private GPUImageFilter mFilter; public final Object mSurfaceChangedWaiter = new Object(); private int mGLTextureId = NO_IMAGE; private SurfaceTexture mSurfaceTexture = null; private final FloatBuffer mGLCubeBuffer; private final FloatBuffer mGLTextureBuffer; private IntBuffer mGLRgbBuffer; int mwidth,mheight,wheight; private int mOutputWidth; private int mOutputHeight; private int mImageWidth; private int mImageHeight; private int mAddedPadding; private final Queue<Runnable> mRunOnDraw; private final Queue<Runnable> mRunOnDrawEnd; private Rotation mRotation; private boolean mFlipHorizontal; private boolean mFlipVertical; private GPUImage.ScaleType mScaleType = GPUImage.ScaleType.CENTER_CROP; public GPUImageRenderer(final GPUImageFilter filter) { mFilter = filter; mRunOnDraw = new LinkedList<Runnable>(); mRunOnDrawEnd = new LinkedList<Runnable>(); mGLCubeBuffer = ByteBuffer.allocateDirect(CUBE.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); mGLCubeBuffer.put(CUBE).position(0); mGLTextureBuffer = ByteBuffer.allocateDirect(TEXTURE_NO_ROTATION.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); setRotation(Rotation.NORMAL,false,false); } @Override public void onSurfaceCreated(final GL10 unused,final EGLConfig config) { GLES20.glClearColor(0,1); GLES20.glDisable(GLES20.GL_DEPTH_TEST); mFilter.init(); } public void onSurfacSize(final int width,final int height) { mwidth=width; mheight=height; } @Override public void onSurfaceChanged(final GL10 gl,final int width,final int height) { if(height>mheight) { mOutputWidth = mwidth; mOutputHeight = mheight; GLES20.glViewport(0,mwidth,mheight); // GLES20.glViewport(0+(mwidth/2),0+(mheight/2),mheight); mFilter.onOutputSizeChanged(mwidth,mheight); } else { mOutputWidth = width; mOutputHeight = height; GLES20.glViewport(0,width,height); mFilter.onOutputSizeChanged(width,height); } // GLES20.glViewport(20,-20,height); GLES20.glUseProgram(mFilter.getProgram()); adjustImageScaling(); synchronized (mSurfaceChangedWaiter) { mSurfaceChangedWaiter.notifyAll(); } } @Override public void onDrawFrame(final GL10 gl) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); runAll(mRunOnDraw); mFilter.onDraw(mGLTextureId,mGLCubeBuffer,mGLTextureBuffer); runAll(mRunOnDrawEnd); if (mSurfaceTexture != null) { mSurfaceTexture.updateTexImage(); } } private void runAll(Queue<Runnable> queue) { synchronized (queue) { while (!queue.isEmpty()) { queue.poll().run(); } } } @Override public void onPreviewFrame(final byte[] data,final Camera camera) { final Size previewSize = camera.getParameters().getPreviewSize(); if (mGLRgbBuffer == null) { mGLRgbBuffer = IntBuffer.allocate(previewSize.width * previewSize.height); } if (mRunOnDraw.isEmpty()) { runOnDraw(new Runnable() { @Override public void run() { GPUImageNativeLibrary.YUVtoRBGA(data,previewSize.width,previewSize.height,mGLRgbBuffer.array()); mGLTextureId = OpenGlUtils.loadTexture(mGLRgbBuffer,previewSize,mGLTextureId); camera.addCallbackBuffer(data); if (mImageWidth != previewSize.width) { mImageWidth = previewSize.width; mImageHeight = previewSize.height; adjustImageScaling(); } } }); } } public void setUpSurfaceTexture(final Camera camera) { runOnDraw(new Runnable() { @Override public void run() { int[] textures = new int[1]; GLES20.glGenTextures(1,textures,0); mSurfaceTexture = new SurfaceTexture(textures[0]); try { camera.setPreviewTexture(mSurfaceTexture); camera.setPreviewCallback(GPUImageRenderer.this); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } }); } public void setFilter(final GPUImageFilter filter) { runOnDraw(new Runnable() { @Override public void run() { final GPUImageFilter oldFilter = mFilter; mFilter = filter; if (oldFilter != null) { oldFilter.destroy(); } mFilter.init(); GLES20.glUseProgram(mFilter.getProgram()); mFilter.onOutputSizeChanged(mOutputWidth,mOutputHeight); } }); } public void setFilter3(final GPUImageFilter filter) { runOnDraw(new Runnable() { @Override public void run() { final GPUImageFilter oldFilter = mFilter; mFilter = filter; // if (oldFilter != null) { // oldFilter.destroy(); // } mFilter.init(); GLES20.glUseProgram(mFilter.getProgram()); mFilter.onOutputSizeChanged(mOutputWidth,mOutputHeight); } }); } public void deleteImage() { runOnDraw(new Runnable() { @Override public void run() { GLES20.glDeleteTextures(1,new int[]{ mGLTextureId },0); mGLTextureId = NO_IMAGE; } }); } public void setImageBitmap(final Bitmap bitmap) { setImageBitmap(bitmap,true); } public void setImageBitmap(final Bitmap bitmap,final boolean recycle) { if (bitmap == null) { return; } runOnDraw(new Runnable() { @Override public void run() { Bitmap resizedBitmap = null; if (bitmap.getWidth() % 2 == 1) { resizedBitmap = Bitmap.createBitmap(bitmap.getWidth() + 1,bitmap.getHeight(),Bitmap.Config.ARGB_8888); Canvas can = new Canvas(resizedBitmap); can.drawARGB(0x00,0x00,0x00); can.drawBitmap(bitmap,null); mAddedPadding = 1; } else { mAddedPadding = 0; } mGLTextureId = OpenGlUtils.loadTexture( resizedBitmap != null ? resizedBitmap : bitmap,mGLTextureId,recycle); if (resizedBitmap != null) { resizedBitmap.recycle(); } mImageWidth = bitmap.getWidth(); mImageHeight = bitmap.getHeight(); adjustImageScaling(); } }); } public void setScaleType(GPUImage.ScaleType scaleType) { mScaleType = scaleType; } protected int getFrameWidth() { return mOutputWidth; } protected int getFrameHeight() { return mOutputHeight; } private void adjustImageScaling() { float outputWidth = mOutputWidth; float outputHeight = mOutputHeight; if (mRotation == Rotation.ROTATION_270 || mRotation == Rotation.ROTATION_90) { outputWidth = mOutputHeight; outputHeight = mOutputWidth; } float ratio1 = outputWidth / mImageWidth; float ratio2 =outputHeight / mImageHeight; float ratioMax = Math.max(ratio1,ratio2); int imageWidthNew = (Math.round(mImageWidth * ratioMax)); int imageHeightNew = (Math.round(mImageHeight * ratioMax)); float ratioWidth = imageWidthNew / (outputWidth); float ratioHeight = imageHeightNew / (outputHeight); float[] cube = CUBE; float[] textureCords = TextureRotationUtil.getRotation(mRotation,mFlipHorizontal,mFlipVertical); if (mScaleType == GPUImage.ScaleType.CENTER_CROP) { float distHorizontal = (1 - 1 / ratioWidth) / 2; float distVertical = (1 - 1 / ratioHeight) / 2; textureCords = new float[]{ addDistance(textureCords[0],distHorizontal),addDistance(textureCords[1],distVertical),addDistance(textureCords[2],addDistance(textureCords[3],addDistance(textureCords[4],addDistance(textureCords[5],addDistance(textureCords[6],addDistance(textureCords[7],}; } else { cube = new float[]{ CUBE[0] * ratioWidth,CUBE[1] * ratioHeight,CUBE[2] * ratioWidth,CUBE[3] * ratioHeight,CUBE[4] * ratioWidth,CUBE[5] * ratioHeight,CUBE[6] * ratioWidth,CUBE[7] * ratioHeight,}; } mGLCubeBuffer.clear(); mGLCubeBuffer.put(cube).position(0); mGLTextureBuffer.clear(); mGLTextureBuffer.put(textureCords).position(0); } private float addDistance(float coordinate,float distance) { return coordinate == 0.0f ? distance : 1 - distance; } public void setRotationCamera(final Rotation rotation,final boolean flipHorizontal,final boolean flipVertical) { setRotation(rotation,flipVertical,flipHorizontal); } public void setRotation(final Rotation rotation,final boolean flipVertical) { mRotation = rotation; mFlipHorizontal = flipHorizontal; mFlipVertical = flipVertical; adjustImageScaling(); } public Rotation getRotation() { return mRotation; } public boolean isFlippedHorizontally() { return mFlipHorizontal; } public boolean isFlippedVertically() { return mFlipVertical; } protected void runOnDraw(final Runnable runnable) { synchronized (mRunOnDraw) { mRunOnDraw.add(runnable); } } protected void runOnDrawEnd(final Runnable runnable) { synchronized (mRunOnDrawEnd) { mRunOnDrawEnd.add(runnable); } } }