android gpu图像渲染问题

时间:2015-12-22 22:28:32

标签: android android-listview gpuimage android-gpuimageview

我正在构建一个Android应用程序,以便在bmp上应用过滤器。我正在使用gpuimage lib。它是如何完成的,bmp显示在一个包含8个过滤器的ListView中。向下/向上滚动时,我们请求过滤bmp(b& w,sepia ...)。由于渲染需要花费时间,我在listview中显示原始bmp,一旦完成就会被过滤后的图像替换

这是活动的方式。

private ListView mFiltersView;


private void FiltersPreview(final Bitmap mBmp) {

    boolean mPreview = true;

    mPreviewBitmap = resizeBitmap(mBmp);

    mCameraImageFiltersAdapter = new CameraImageFiltersAdapter(this, mPreviewBitmap, mPreview);
    mFiltersView.setAdapter(mCameraImageFiltersAdapter);
    mFiltersView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            mCameraImageFiltersAdapter.cancel();
            mFiltersView.cancelPendingInputEvents();
            mFiltersView.setAdapter(null);
            final CameraFiltersFactory effect = (CameraFiltersFactory) v.findViewById(R.id.filteredImage).getTag();
            BufferAnimationDrawable Loading = new BufferAnimationDrawable(getBaseContext());
            Loading.setPrimaryColor(0xfffb633e);
            LoadingScreen.setImageDrawable(Loading);
            LoadingScreen.setVisibility(View.VISIBLE);
            mFiltersView.setVisibility(View.GONE);
            getActionBar().hide();

                if(mBmp == null) Log.d(TAG,"mBitmap is null");
                effect.save(mBmp, position, new GPUImage.OnPictureSavedListener() {
                    @Override
                    public void onPictureSaved(Uri uri) {
                        final Intent previewIntent = new Intent(FiltersSelectionActivity.this, PicturePreviewActivity.class);
                        previewIntent.setData(uri);
                        previewIntent.setAction(mActionTypes.toString());
                        previewIntent.putExtra("Type", "Filtered");
                        startActivityForResult(previewIntent, 0);
                    }
                });
            }

    });
}

mCameraImageFiltersAdapter定义为:

 public CameraImageFiltersAdapter(/*Activity activity, */Context c, Bitmap current, boolean isPreview) {
    mContext = c;
    mPreview = isPreview;
    mCurrentBitmap = current;

    mFilterIds = CAMERA_IMAGE_FILTERS == null
        || CAMERA_IMAGE_FILTERS.length == 0 ?
        mFilterIds : CAMERA_IMAGE_FILTERS;
    mFakeBitmap = mCurrentBitmap;
    mFakeBitmap.setDensity(0);
    mExecutorService = Executors.newFixedThreadPool(5);


}

private final Handler handler = new Handler();// handler to display images

public int getCount() { return mFilterIds.length; }
public long getItemId(int position) { return 0; }
public Object getItem(int position) { return null; }
@Override public int getViewTypeCount() { return mFilterIds.length; }
@Override public int getItemViewType(int position) { return position; }

final int stub_id = R.drawable.filter_preview_stub;

public ImageView filteredImage = null;
public TextView filteredText = null;

@SuppressLint("InflateParams")
public View getView(int position, View convertView, ViewGroup parent) {

    mPosition = position;
    if (convertView == null) {

        convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_filter, null);
        filteredImage = (ImageView) convertView.findViewById(R.id.filteredImage);
        filteredImage.setImageBitmap(mFakeBitmap);

        filteredText = (TextView) convertView.findViewById(R.id.textview);

        queueFiltered(filteredImage, mPosition, filteredText);

    }

    return convertView;
}

private void queueFiltered(final ImageView view, final int position, final TextView text) {

    final CameraFiltersFactory holder = new CameraFiltersFactory(mContext, view, text);
    if(holder != null)
        mExecutorService.submit(new FilterLoader(holder, position));
}

public void cancel() {
    if(mExecutorService != null) mExecutorService.shutdownNow();
}

CameraFilterFactoy只是一个易于使用的类来访问GPUImage

 public class CameraFiltersFactory {

private static final String TAG = CameraFiltersFactory.class.getSimpleName();

private final ImageView mImageView;
private final GPUImage mCameraImage;
private Bitmap mFilteredBitmap;
private int mCurrentEffect;
private Context mContext;
private Activity mActivity = null;
private TextView mFiltersText;

public CameraFiltersFactory(Context c, ImageView filteredImage, TextView filteredText) {

    mImageView = filteredImage;
    mImageView.setTag(this);

    mContext = c;
    mCameraImage = new GPUImage(mContext);

    if(filteredText != null) {
        mFiltersText = filteredText;
        mFiltersText.setVisibility(View.VISIBLE);
    }
    if(mImageView != null) mActivity = (Activity) mContext;
}

public void generateFilteredBitmap(Bitmap bmp, int filtertype, boolean isPreview) {
    mCurrentEffect = filtertype;

    switch (mCurrentEffect) {
     case R.id.blackandwhite:
         mCameraImage.setFilter(new GPUImagePlusGrayscaleFilter(isPreview));
         break;
     case R.id.cool:
         mCameraImage.setFilter(new GPUImagePlusCoolFilter(isPreview));
         break;
     case R.id.cool2:
         mCameraImage.setFilter(new GPUImagePlusCool2Filter(isPreview));
         break;
     case R.id.faded:
         mCameraImage.setFilter(new GPUImagePlusFadedFilter(mContext, isPreview));
        break;
     case R.id.hipster:
         mCameraImage.setFilter(new GPUImagePlusHipsterFilter(mContext, isPreview));
        break;
     case R.id.sepia:
         mCameraImage.setFilter(new GPUImagePlusSepiaFilter(isPreview));
        break;
     case R.id.vivid:
         mCameraImage.setFilter(new GPUImagePlusVividFilter(isPreview));
         break;
     case R.id.warm:
         mCameraImage.setFilter(new GPUImagePlusWarmFilter(mContext, isPreview));
         break;
     default:
         Log.d("NONE", "None FAIT CHIER");
         break;
    }

    mCameraImage.deleteImage();
    mCameraImage.setImage(bmp);
    mFilteredBitmap = mCameraImage.getBitmapWithFilterApplied();

}



@SuppressLint("SimpleDateFormat")
public void save(Bitmap bitmap, int filter_id, GPUImage.OnPictureSavedListener ofsl) {
    Log.d("NONE", "Save request with filter: "+filter_id);
    generateFilteredBitmap(bitmap, filter_id, false);
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String fileName = timeStamp + ".jpg";
    mCameraImage.saveToPictures(mFilteredBitmap, CameraSettings.CAMERA_ROLL_FOLDER, fileName, true, ofsl);
}

}

此代码在列表视图中正常工作。

一旦我点击ListView中的图片,我就会得到他的位置,从适配器停止Executor并向FilterFactory请求渲染。

如果在列表视图中我等待所有预览列表图像显示过滤器渲染,然后单击,过滤器正确应用于原始bmp。

如果我正在快速向下滚动并且GPU正在进行渲染预览,然后单击,则不会过滤原始bmp。我已经检查过,在这两种情况下,当我单击列表视图时给出正确的过滤器位置和那个案例。似乎如果正在进行渲染,我将无法取消并要求新的渲染。

知道为什么吗?不知道我是否可以取消当前的GPU渲染并开始新的渲染。 ?

由于

1 个答案:

答案 0 :(得分:0)

使用gpuImage.deleteImage();从gpu映像中获取位图后,适配器类中的方法。

在将图像设置为GPUImage之前,请创建图像缩略图。所以它会加载很快。

GPUImaage gpuImage=new GPUImage(context);
gpuImage.setImage(your image);
gpuImage.setFilter(choose your filter);
gpuImage.requestRender();

imageView.setImageBitmap(gpuImage.getBitmapWithFilterApplied());

gpuImage.deleteImage();