2015-12-22 68 views
0

我目前正在构建一个android应用程序以在bmp上应用滤镜。我正在使用gpuimage lib。它是如何完成的是bmp显示在包含8个过滤器的ListView中。当向下滚动/向上滚动时,我们请求过滤bmp(b & w,棕褐色...)。由于渲染需要时间,我在我的列表视图中显示原始bmp,并且在完成后它被替换为已过滤的图像android gpu图像渲染问题

以下是活动如何执行此操作。

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渲染,并开始一个新的。 ?

感谢

回答

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();