画像にフィルタリングを追加しようとしていますが、GLSurfaceView
を使用してエフェクトを実行時に変更すると表示されますが、エフェクト間でレンダリングすると、GLSurfaceViewがエフェクトをレンダリングするには遅すぎる
私のコードがある...
public class EffictActivity extends AppCompatActivity implements GLSurfaceView.Renderer{
private RecyclerView recList;
int mCurrentEffect;
private GLSurfaceView mEffectView;
private int[] mTextures = new int[2];
private EffectContext mEffectContext;
private Effect mEffect;
Bitmap bm;
private TextureRenderer mTexRenderer = new TextureRenderer();
private int mImageWidth;
EGL10 egl;
private int mImageHeight;
Button saveImage;
private boolean mInitialized = false;
private volatile boolean saveFrame;
ProgressDialog mDialog;
public void setCurrentEffect(int effect) {
mCurrentEffect = effect;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_effict);
saveImage = (Button) findViewById(R.id.effectSave) ;
mEffectView = (GLSurfaceView) findViewById(R.id.effectsview);
mEffectView.setEGLContextClientVersion(2);
mEffectView.setRenderer(this);
mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
mCurrentEffect = 0;
mDialog = Utils.SetProgressBar(mDialog, this);
new CountDownTimer(3000 ,1000) {
@Override
public void onTick(long millisUntilFinished) {
mDialog.show();
}
@Override
public void onFinish() {
mDialog.dismiss();
}
}.start();
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recList = (RecyclerView) findViewById(R.id.rc_filter);
recList.setHasFixedSize(true);
recList.setLayoutManager(layoutManager);
FilterAdapterFactory filterAdapter = new FilterAdapterFactory(this);
recList.setAdapter(filterAdapter);
recList.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
setCurrentEffect(position);
mEffectView.requestRender();
}
}));
saveImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// if (mInterstitialAd.isLoaded()) {
// mInterstitialAd.show();
// }
SaveImage(bm);
}
});
}
private void loadTextures() {
// Generate textures
GLES20.glGenTextures(2, mTextures, 0);
String root = Environment.getExternalStorageDirectory().toString();
Bitmap bitmap = BitmapFactory.decodeFile(root + "/HijabPhoto/" + getIntent().getStringExtra("path"));
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Set texture parameters
GLToolbox.initTexParams();
bitmap.recycle();
}
private void initEffect() {
EffectFactory effectFactory = mEffectContext.getFactory();
if (mEffect != null) {
mEffect.release();
}
/**
* Initialize the correct effect based on the selected menu/action item
*/
switch (mCurrentEffect) {
case 0:
break;
case 1:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_AUTOFIX);
mEffect.setParameter("scale", 0.5f);
break;
case 2:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_BLACKWHITE);
mEffect.setParameter("black", .1f);
mEffect.setParameter("white", .7f);
break;
case 3:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_BRIGHTNESS);
mEffect.setParameter("brightness", 2.0f);
break;
case 4:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_CONTRAST);
mEffect.setParameter("contrast", 1.4f);
break;
case 5:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_CROSSPROCESS);
break;
case 6:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_DOCUMENTARY);
break;
case 7:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_DUOTONE);
mEffect.setParameter("first_color", Color.YELLOW);
mEffect.setParameter("second_color", Color.DKGRAY);
break;
case 8:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FILLLIGHT);
mEffect.setParameter("strength", .8f);
break;
case 9:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FISHEYE);
mEffect.setParameter("scale", .5f);
break;
case 10:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP);
mEffect.setParameter("vertical", true);
break;
case 11:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP);
mEffect.setParameter("horizontal", true);
break;
case 12:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_GRAIN);
mEffect.setParameter("strength", 1.0f);
break;
case 13:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_GRAYSCALE);
break;
case 14:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_LOMOISH);
break;
case 15:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_NEGATIVE);
break;
case 16:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_POSTERIZE);
break;
case 17:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_ROTATE);
mEffect.setParameter("angle", 180);
break;
case 18:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SATURATE);
mEffect.setParameter("scale", .5f);
break;
case 19:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SEPIA);
break;
case 20:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SHARPEN);
break;
case 21:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_TEMPERATURE);
mEffect.setParameter("scale", .9f);
break;
case 22:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_TINT);
mEffect.setParameter("tint", Color.MAGENTA);
break;
case 23:
mEffect = effectFactory.createEffect(EffectFactory.EFFECT_VIGNETTE);
mEffect.setParameter("scale", .5f);
break;
default:
break;
}
}
private void applyEffect() {
mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]);
}
private void renderResult() {
if (mCurrentEffect != 0) {
// if no effect is chosen, just render the original bitmap
mTexRenderer.renderTexture(mTextures[1]);
} else {
saveFrame=true;
// render the result of applyEffect()
mTexRenderer.renderTexture(mTextures[0]);
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (mTexRenderer != null) {
mTexRenderer.updateViewSize(width, height);
}
}
@Override
public void onDrawFrame(GL10 gl) {
egl = (EGL10) EGLContext.getEGL();
gl = (GL10)egl.eglGetCurrentContext().getGL();
if (!mInitialized) {
// Only need to do this once
mEffectContext = EffectContext.createWithCurrentGlContext();
mTexRenderer.init();
loadTextures();
mInitialized = true;
}
if (mCurrentEffect != 0) {
// if an effect is chosen initialize it and apply it to the texture
initEffect();
applyEffect();
}
renderResult();
bm = createBitmapFromGLSurface(0 ,0, mImageWidth , mImageHeight , gl);
SaveImage(bm);
}
private void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/HijabPhoto");
myDir.mkdirs();
String fileName = getIntent().getStringExtra("path");
File file = new File(myDir, fileName);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
Toast.makeText(EffictActivity.this, getString(R.string.imageSavedSuccrss), Toast.LENGTH_SHORT).show();
Log.w("FILE PATH===", file.getPath().toString());
String path = file.getPath().toString();
addImageToGallery(path, EffictActivity.this);
out.flush();
out.close();
// if (mInterstitialAd.isLoaded()) {
// mInterstitialAd.show();
// }
Intent sharin = new Intent(EffictActivity.this,ShareActivity.class);
sharin.putExtra("path",fileName);
Log.w("file path",""+file.getPath().toString());
startActivity(sharin);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void addImageToGallery(final String filePath, final Context context) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, filePath);
context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl)
throws OutOfMemoryError {
int bitmapBuffer[] = new int[w * h];
int bitmapSource[] = new int[w * h];
IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
intBuffer.position(0);
try {
gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);
int offset1, offset2;
for (int i = 0; i < h; i++) {
offset1 = i * w;
offset2 = (h - i - 1) * w;
for (int j = 0; j < w; j++) {
int texturePixel = bitmapBuffer[offset1 + j];
int blue = (texturePixel >> 16) & 0xff;
int red = (texturePixel << 16) & 0x00ff0000;
int pixel = (texturePixel & 0xff00ff00) | red | blue;
bitmapSource[offset2 + j] = pixel;
}
}
} catch (GLException e) {
return null;
}
return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888);
}
}
任意の助けてください...
onSurfaceCreated()メソッドは空で、すべての作業はonDrawFrame()メソッドにあります。最良の選択肢はglReadPixels()であり、GLスレッドから離れて処理するために別のスレッドにデータを送信することです。 – WLGfx
コードでこれを行う方法を教えてください。 –