Предотвратить мерцание при обновлении предварительного просмотра камеры
Я использую кадры, полученные с USB-камеры (с помощью библиотеки UVCCamera), и применяю эффект размытия с помощью RenderScript. Формат кадра - NV21. Эффект размытия, созданный RenderScript, работает очень хорошо. Однако, когда я хочу применить другие эффекты, используя Zomato Filters, я получаю мерцающий результат, хотя эффекты применяются.
А затем в методе onFrame я получаю кадры с USB-камеры и применяю фильтры в соответствии со значениями панели поиска:
private final IFrameCallback mIFrameCallback = new IFrameCallback() {
@Override
public void onFrame(final ByteBuffer frame) {
frame.clear();
synchronized (bitmap) {
// bitmap.copyPixelsFromBuffer(frame);
byte[] bytes = new byte[frame.remaining()];
frame.get(bytes);
MainActivity.this.allocationYUV.copyFrom(bytes);
MainActivity.this.ApplyEffect = false;
if (!MainActivity.this.ApplyEffect) {
MainActivity.this.intrinsicYuvToRGB.setInput(MainActivity.this.allocationYUV);
MainActivity.this.intrinsicYuvToRGB.forEach(MainActivity.this.allocationBlur);
MainActivity.this.intrinsicBlur.forEach(MainActivity.this.allocationBlur, MainActivity.this.allocationOut);
}
MainActivity.this.allocationOut.syncAll(128);
//Here, apply the three other effects
int brightness = mSeekbar1.getProgress();
int contrast = mSeekbar2.getProgress();
int saturation = mSeekbar3.getProgress();
//The following checks are done to prevent unnecessary image processing
Filter myFilter = new Filter();
if(brightness != 0) {
BrightnessSubfilter bs = new BrightnessSubfilter(brightness * 32);
bs.setTag("brightness");
myFilter.addSubFilter(bs);
}
else { //If 0, then remove the filter altogether
myFilter.removeSubFilterWithTag("brightness");
}
if(contrast != 0) {
ContrastSubfilter cs = new ContrastSubfilter(contrast * 32);
cs.setTag("contrast");
myFilter.addSubFilter(cs);
mContrastChanged = false;
}
else {
myFilter.removeSubFilterWithTag("contrast");
}
if(saturation != 0) {
SaturationSubfilter ss = new SaturationSubfilter(saturation * 32);
ss.setTag("saturation");
myFilter.addSubFilter(ss);
mSaturationChanged = false;
}
else {
myFilter.removeSubFilterWithTag("saturation");
}
mOutBitmap = myFilter.processFilter(bitmap);
mImageView.post(mUpdateImageTask);
}
}
};
private final Runnable mUpdateImageTask = new Runnable() {
@Override
public void run() {
synchronized (bitmap) {
mImageView.setImageBitmap(mOutBitmap);
}
}
};
Я думаю, что выделения RenderScript для размытия довольно типичны, поэтому я не добавил их для экономии места и уменьшения сложности.