/** 获得功能表底部背景图片:当拖动图标至桌面时的背景效果图 */ public MImage getMoveToDeskBg() { if (isVertical()) { if (mMoveToDesk_v == null) { try { mMoveToDesk_v = generateMImage(R.drawable.appfunc_movetodesk, getScreenWidth(), getRealNum(85), 0); } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); } } return mMoveToDesk_v; } else { if (mMoveToDesk_h == null) { try { mMoveToDesk_h = generateMImage( R.drawable.appfunc_movetodesk, getScreenHeight(), getRealNum(85), -90.0f); } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); } } return mMoveToDesk_h; } }
/** 获得功能表底部背景图片: 底层为BitmapDrawable格式 */ public MImage getBottomBg() { if (isVertical()) { if (mBottomBg_v == null) { try { mBottomBg_v = generateMImage(R.drawable.shorcut_slaver, getScreenWidth(), getRealNum(85), 0); } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); } } return mBottomBg_v; } else { if (mBottomBg_h == null) { try { mBottomBg_h = generateMImage(R.drawable.shorcut_slaver, getScreenHeight(), getRealNum(85), -90.0f); } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); } } return mBottomBg_h; } }
/** * 获取关闭高光图标的副本 * * @return */ public BitmapDrawable getColseLightIconCopy() { try { if (mCloseLightIcon == null) { if (mThemeController == null) { mThemeController = AppFuncFrame.getThemeController(); } BitmapDrawable origImg = (BitmapDrawable) mThemeController.getDrawable( mThemeController.getThemeBean().mAppIconBean.mKillAppLight); if (origImg != null) { Bitmap copy = origImg.getBitmap().copy(Bitmap.Config.ARGB_8888, true); if (copy != null) { mCloseLightIcon = new BitmapDrawable(mContext.getResources(), copy); } } } } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); } catch (Exception e) { e.printStackTrace(); } return mCloseLightIcon; }
/** * 获取编辑文件夹高光图标的副本 * * @return */ public BitmapDrawable getEditLightIconCopy() { try { if (mEditLightIcon == null) { // BitmapDrawable origImg = (BitmapDrawable) mActivity // .getResources().getDrawable( // R.drawable.eidt_folder_light); if (mThemeController == null) { mThemeController = AppFuncFrame.getThemeController(); } BitmapDrawable origImg = (BitmapDrawable) mThemeController.getDrawable( mThemeController.getThemeBean().mAppIconBean.mEditHighlightFolder); if (origImg != null) { Bitmap copy = origImg.getBitmap().copy(Bitmap.Config.ARGB_8888, true); if (copy != null) { mEditLightIcon = new BitmapDrawable(mContext.getResources(), copy); } } } } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); } catch (Exception e) { e.printStackTrace(); } return mEditLightIcon; }
/** * 获取卸载图标的副本 * * @return */ public BitmapDrawable getKillIconCopy() { try { if (mKillImg == null) { // BitmapDrawable origImg = (BitmapDrawable) mActivity // .getResources().getDrawable(R.drawable.kill); if (mThemeController == null) { mThemeController = AppFuncFrame.getThemeController(); } BitmapDrawable origImg = (BitmapDrawable) mThemeController.getDrawable( mThemeController.getThemeBean().mAppIconBean.mDeletApp); if (origImg != null) { Bitmap copy = origImg.getBitmap().copy(Bitmap.Config.ARGB_8888, true); if (copy != null) { mKillImg = new BitmapDrawable(mContext.getResources(), copy); } } } } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); } catch (Exception e) { e.printStackTrace(); } return mKillImg; }
/** * 获得格式为Drawable的图片 * * @param drawableId * @return */ public Drawable getDrawable(int drawableId) { Drawable img = null; try { if (mPublicResources.containsKey(drawableId)) { // 与主题无关的资源不保存在主题资源管理器中 img = getDrawableFromMainPkg(drawableId); } else { img = mPicManager.getViewDrawable(drawableId); } } catch (OutOfMemoryError e) { Log.d("XViewFrame", "Hoops! Out of Memeory"); e.printStackTrace(); OutOfMemoryHandler.handle(); } return img; }
private Bitmap createNoCropBitmap() { Bitmap bitmap = mBitmap; try { if (null != bitmap) { int bmpW = bitmap.getWidth(); int bmpH = bitmap.getHeight(); float wScale = (float) mOutputX / (float) bmpW; float hScale = (float) mOutputY / (float) bmpH; float scale = wScale < hScale ? wScale : hScale; boolean needScale = scale < 1; boolean needYFit = false; if (scale < 1) { needYFit = (int) (bmpH * scale) < mOutputY - 1; // 由于缩放误差1个单位 } else { needYFit = bmpH < mOutputY; } boolean needXFit = false; // for dock if (scale < 1) { needXFit = (int) (bmpW * scale) < mOutputX - 1; // 由于缩放误差1个单位 } else { needXFit = bmpW < mOutputX; } if (needScale) { Bitmap tempbitmap = BitmapUtility.createScaledBitmap(bitmap, (int) (bmpW * scale), (int) (bmpH * scale)); bitmap.recycle(); bitmap = tempbitmap; } if (needYFit || needXFit) { Bitmap tempbitmap = BitmapUtility.createBitmap(bitmap, mOutputX, mOutputY); bitmap.recycle(); bitmap = tempbitmap; } } } catch (OutOfMemoryError e) { OutOfMemoryHandler.handle(); e.printStackTrace(); bitmap = null; } catch (Exception e) { e.printStackTrace(); bitmap = null; } return bitmap; }
private boolean decodeBitmapStreamSafe(Uri target) { String path = uriToFilePath(target, this); int degree = 0; if (path != null) { degree = readBitmapDegree(path); } InputStream is = null; boolean bool = true; int scale = 1; Options opt = new Options(); while (bool) { try { is = mContentResolver.openInputStream(target); opt.inSampleSize = scale; mBitmap = null; mBitmap = BitmapFactory.decodeStream(is, null, opt); mBitmap = postRotateToBitmap(degree, mBitmap); mHasApha = mBitmap.hasAlpha(); bool = false; return true; } catch (OutOfMemoryError e) { // 如果解碼大圖片,出现爆内存,则每次缩放一半 OutOfMemoryHandler.handle(); scale *= 2; if (scale > (1 << 10)) { // 防止异常死循环 return false; } } catch (Throwable e) { // TODO: handle Throwable bool = false; return false; } } return false; }
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle); mContentResolver = getContentResolver(); requestWindowFeature(Window.FEATURE_NO_TITLE); // MenuHelper.showStorageToast(this); Intent intent = getIntent(); Bundle extras = intent.getExtras(); if (extras != null) { // if (extras.getString("circleCrop") != null) { // mCircleCrop = true; // mAspectX = 1; // mAspectY = 1; // } mSaveUri = (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT); if (mSaveUri != null) { String outputFormatString = extras.getString("outputFormat"); if (outputFormatString != null) { mOutputFormat = Bitmap.CompressFormat.valueOf(outputFormatString); } } else { mSetWallpaper = extras.getBoolean("setWallpaper"); } mBitmap = (Bitmap) extras.getParcelable("data"); mAspectX = extras.getInt("aspectX"); mAspectY = extras.getInt("aspectY"); mOutputX = extras.getInt("outputX"); mOutputY = extras.getInt("outputY"); mScale = extras.getBoolean("scale", false); mScaleUp = extras.getBoolean("scaleUpIfNeeded", false); // mDoFaceDetection = extras.containsKey("noFaceDetection") // ? !extras.getBoolean("noFaceDetection") // : true; android.content.res.Resources resources = getResources(); int id = extras.getInt("arrowHorizontal", -1); if (id != -1) { mResizeDrawableWidth = resources.getDrawable(id); } id = extras.getInt("arrowVertical", -1); if (id != -1) { mResizeDrawableHeight = resources.getDrawable(id); } // id = extras.getInt("arrowDiagonal", -1); // if(id != -1){ // mResizeDrawableDiagonal = resources.getDrawable(id); // } } if (mBitmap == null) { Uri target = intent.getData(); try { decodeBitmapStreamSafe(target); } catch (OutOfMemoryError e) { OutOfMemoryHandler.handle(); } catch (Throwable e) { e.printStackTrace(); } // TODO // if (mImage != null) { // // Don't read in really large bitmaps. Use the (big) thumbnail // // instead. // // TODO when saving the resulting bitmap use the // // decode/crop/encode api so we don't lose any resolution. // mBitmap = mImage.thumbBitmap(IImage.ROTATE_AS_NEEDED); // } } if (mBitmap == null) { setResult(RESULT_CANCELED); finish(); return; } // Make UI fullscreen. getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.cropimage); mImageView = (CropImageView) findViewById(R.id.image); findViewById(R.id.discard) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { setResult(RESULT_CANCELED); finish(); } }); findViewById(R.id.crop) .setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { onSaveClicked(); } }); final Button btn = (Button) findViewById(R.id.no_crop); btn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // if (mNeedCrop) // { // mImageView.setImageBitmapResetBase(mBitmap, true); // mImageView.remove(mCrop); // mCrop = null; // // btn.setText(R.string.crop_text); // } // else // { // makeDefault(); // mImageView.requestLayout(); // mCrop = mImageView.mHighlightViews.get(0); // mCrop.setFocus(true); // // btn.setText(R.string.no_crop_text); // } // mNeedCrop = !mNeedCrop; mNeedCrop = false; onSaveClicked(); } }); // startFaceDetection(); mImageView.setImageBitmapResetBase(mBitmap, true); makeDefault(); mCrop = mImageView.mHighlightViews.get(0); mCrop.setFocus(true); }
private void onSaveClicked() { if (!mNeedCrop) { Bitmap nocropBitmap = createNoCropBitmap(); mImageView.clear(); if (nocropBitmap != mBitmap) { mBitmap.recycle(); mBitmap = null; } if (null != nocropBitmap) { // Return the cropped image directly or save it to the specified // URI. Bundle myExtras = getIntent().getExtras(); if (myExtras != null && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) { Bundle extras = new Bundle(); extras.putParcelable("data", nocropBitmap); setResult( RESULT_OK, (new Intent()).setAction(ICustomAction.ACTION_INLINE_DATA).putExtras(extras)); finish(); } else { final Bitmap b = nocropBitmap; final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage; Util.startBackgroundJob( this, null, getResources().getString(msdId), new Runnable() { @Override public void run() { saveOutput(b); } }, mHandler); } } else { setResult(RESULT_CANCELED); finish(); } return; } // TODO this code needs to change to use the decode/crop/encode single // step api so that we don't require that the whole (possibly large) // bitmap doesn't have to be read into memory if (mCrop == null) { return; } if (mSaving) { return; } mSaving = true; Bitmap croppedImage = null; Bitmap.Config bmpConfig = mHasApha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.ARGB_8888; // If the output is required to a specific size, create an new image // with the cropped image in the center and the extra space filled. if (mOutputX != 0 && mOutputY != 0 && !mScale) { // Don't scale the image but instead fill it so it's the // required dimension try { croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, bmpConfig); } catch (OutOfMemoryError e) { // 创建失败 e.printStackTrace(); OutOfMemoryHandler.handle(); Toast.makeText(this, getString(R.string.err_out_of_memory), Toast.LENGTH_SHORT); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); mBitmap = null; setResult(RESULT_CANCELED); finish(); return; } Canvas canvas = new Canvas(croppedImage); Rect srcRect = mCrop.getCropRect(); Rect dstRect = new Rect(0, 0, mOutputX, mOutputY); int dx = (srcRect.width() - dstRect.width()) / 2; int dy = (srcRect.height() - dstRect.height()) / 2; // If the srcRect is too big, use the center part of it. srcRect.inset(Math.max(0, dx), Math.max(0, dy)); // If the dstRect is too big, use the center part of it. dstRect.inset(Math.max(0, -dx), Math.max(0, -dy)); // Draw the cropped bitmap in the center canvas.drawBitmap(mBitmap, srcRect, dstRect, null); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); } else { Rect r = mCrop.getCropRect(); // int width = r.width(); // int height = r.height(); // If we are circle cropping, we want alpha channel, which is the // third param here. try { croppedImage = Bitmap.createBitmap(mOutputX, mOutputY, bmpConfig); } catch (OutOfMemoryError e) { e.printStackTrace(); OutOfMemoryHandler.handle(); // 创建失败 // Toast.makeText(this, getString(R.string.err_out_of_memory), // Toast.LENGTH_SHORT).show(); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); setResult(RESULT_CANCELED); finish(); return; } Canvas canvas = new Canvas(croppedImage); canvas.setDrawFilter( new PaintFlagsDrawFilter( 0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); // 在有缩放的情况下需要提高绘图质量 Rect dstRect = new Rect(0, 0, mOutputX, mOutputY); canvas.drawBitmap(mBitmap, r, dstRect, null); // Release bitmap memory as soon as possible mImageView.clear(); mBitmap.recycle(); // if (mCircleCrop) { // // OK, so what's all this about? // // Bitmaps are inherently rectangular but we want to return // // something that's basically a circle. So we fill in the // // area around the circle with alpha. Note the all important // // PortDuff.Mode.CLEAR. // Canvas c = new Canvas(croppedImage); // Path p = new Path(); // p.addCircle(width / 2F, height / 2F, width / 2F, // Path.Direction.CW); // c.clipPath(p, Region.Op.DIFFERENCE); // c.drawColor(0x00000000, PorterDuff.Mode.CLEAR); // } // If the required dimension is specified, scale the image. // if (mOutputX != 0 && mOutputY != 0 && mScale) { // croppedImage = Util.transform(new Matrix(), croppedImage, // mOutputX, mOutputY, mScaleUp, Util.RECYCLE_INPUT); // } } mImageView.setImageBitmapResetBase(croppedImage, true); mImageView.center(true, true); mImageView.mHighlightViews.clear(); // Return the cropped image directly or save it to the specified URI. Bundle myExtras = getIntent().getExtras(); if (myExtras != null && (myExtras.getParcelable("data") != null || myExtras.getBoolean("return-data"))) { Bundle extras = new Bundle(); extras.putParcelable("data", croppedImage); setResult( RESULT_OK, (new Intent()).setAction(ICustomAction.ACTION_INLINE_DATA).putExtras(extras)); finish(); } else { final Bitmap b = croppedImage; final int msdId = mSetWallpaper ? R.string.wallpaper : R.string.savingImage; Util.startBackgroundJob( this, null, getResources().getString(msdId), new Runnable() { @Override public void run() { saveOutput(b); } }, mHandler); } }