Android的:内存从图纸缓存创建和扭曲后的位图 [英] Android: Out of memory after creating and skewing Bitmap from Drawing Cache

查看:113
本文介绍了Android的:内存从图纸缓存创建和扭曲后的位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的做法是:

我有三个 TextViews (嵌套在的LinearLayout ),我希望他们有一个倾斜的效果,所以它看起来像他们在墙上的(看看下面的图片)。由于用户可以改变背景(不同的墙),我现在用的是 DrawingCache 的LinearLayout ,扭曲它,最后呈现在被放置在背景图像之上的透明图像..

I have three TextViews (nested in a LinearLayout) and I want them to have a skewing effect, so that it looks like they are at a wall (look at the image below). Since the user can change the background (different wall), I am using the DrawingCache from the LinearLayout, skew it, and finally render it in a transparent image which is placed above the background image..

要确保文本是在每个设备合适的位置,我想出了一个解决方案,有一个背景图片(720x1022),并呈现文本到一个透明的图像,并将其放置在正确的与图形坐标相同的大小(720x1022)。在应用中,图片被缩放并置于相同的方式。也许这是不是最好的办法,因为有时候(假设1次满分10分)我遇到了OutOfMemory错误。

To ensure that the text is at the right position at every device, I came up with the solution to have a background image (720x1022) and render the text to a transparent image and place it at the right coordinates in a graphic with the same size (720x1022). In the app, pictures are scaled and placed the same way. Maybe it's not the best idea, because sometimes (let's say 1 time out of 10) I am running into an OutOfMemory Error.

java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:689)
at android.graphics.Bitmap.createBitmap(Bitmap.java:666)
at android.graphics.Bitmap.createBitmap(Bitmap.java:633)
//or

java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785)
at android.content.res.Resources.loadDrawable(Resources.java:1965)
at android.content.res.TypedArray.getDrawable(TypedArray.java:601)

和堆突然增长。

  Grow heap (frag case) to 73.520MB for 11773456-byte allocation

它不会崩溃每次(假设1满分10分),而不是在相同的位置。下面是我实现的:

It doesn't crash every time (let's say 1 out of 10), and not at the same position. Here's my implementation:

首先,我们从这些嵌套在的LinearLayout并将其扩展到一个特定的高度和宽度的TextViews用户输入(#2)来执行偏斜矩阵(#3)。

First, we get the user input from the TextViews which are nested in a LinearLayout and scale it to a specific height and width (#2) to perform the skewing matrix (#3).

//#1 get Text from TextViews
View test = findViewById(R.id.signFakeContainer);
test.setDrawingCacheEnabled(true);
Bitmap mOfferText = test.getDrawingCache();

//#2 scale Text to specific width & height to perform skew effect
Bitmap mScaledBitmap = Bitmap.createScaledBitmap(mOfferText, 560, 720, false);

int mTextViewWidth = mScaledBitmap.getWidth();
int mTextViewHeight = mScaledBitmap.getHeight();

//#3 create skewing matrix
Matrix mMatrix2 = new Matrix();
float[] mStartSrc = new float[] { 0, 0, mTextViewWidth, 0, mTextViewWidth, mTextViewHeight, 0, mTextViewHeight };
float[] mDestSrc = new float[] { 0, 4f, 520f, 0f, 552f, 704f, 22f, 720f };
mMatrix2.setPolyToPoly(mStartSrc, 0, mDestSrc, 0, 4);

//#4 perform skewing
Bitmap mStrechtedTextView = Bitmap.createBitmap(mScaledBitmap, 0, 0, mTextViewWidth, mTextViewHeight, mMatrix2, false);

//#5 place 560x720 image in 720x1022 image at specific coordinates, to ensure its right position 
Bitmap bmp = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.transparent_dummy), 720, 1022, false);
Canvas comboImage = new Canvas(bmp);
comboImage.drawBitmap(mStrechtedTextView, 98, 110, null);

//#6 set rendered textview to image
ImageView mOfferImageView = (ImageView) findViewById(R.id.choose_sign_offer_image);
mOfferImageView.setImageBitmap(bmp);

我发现这真的好文章:<一href=\"http://stackoverflow.com/questions/477572/strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object\">Strange内存不足的问题,而加载图像到一个位图对象但它仍然没有解决我的问题。我想我还是有太多的 createBitmaps 。也许有更好的方式来做到这一点,所以我很高兴为每个建议!

I found this really good article: Strange out of memory issue while loading an image to a Bitmap object but still it doesn't solve my issue. I guess I still have too many createBitmaps. Maybe there's a better way to do this, so I'm happy for every suggestion!

推荐答案

我们的这种情况下,最终的解决方案,是渲染<$ C $的使用的AsyncTask 的C>图片。我们通过一个参考的LinearLayout 其中包括 TextViews (这就是我们渲染),一个为参考的ImageView 在这里我们插入所呈现的画面和进度的参考图像渲染后的墙根

Our final solution for this case, was the use of an AsyncTask for rendering the Image. We pass a reference to the LinearLayout which included the TextViews (this is what we are rendering), a reference for the ImageView where we insert the rendered picture and a reference to ProgressBar which is hided after the Image is rendered

public class RenderBitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
  private final WeakReference<ImageView> imageViewReference;
  private final LinearLayout signViewReference;
  private final ProgressBar progressBar;

  public RenderBitmapWorkerTask(ImageView imageView, LinearLayout signView, ProgressBar mProgressBar) {
      // Use a WeakReference to ensure the ImageView can be garbage collected
      imageViewReference = new WeakReference<ImageView>(imageView);
      signViewReference = signView;
      progressBar = mProgressBar;
  }

  // Decode image in background.
  @Override
  protected Bitmap doInBackground(Integer... params) {
    signViewReference.setDrawingCacheEnabled(true);

    Bitmap mOfferText = signViewReference.getDrawingCache();

    int mTextViewWidth = 560;
        int mTextViewHeight = 720;

        mOfferText = Bitmap.createScaledBitmap(mOfferText, mTextViewWidth, mTextViewHeight, false);

        Matrix mMatrix2 = new Matrix();
        float[] mStartSrc = new float[] { 0, 0, mTextViewWidth, 0, mTextViewWidth, mTextViewHeight, 0, mTextViewHeight };
        float[] mDestSrc = new float[] { 0, 4f, 520f, 0f, 552f, 704f, 22f, 720f };
        mMatrix2.setPolyToPoly(mStartSrc, 0, mDestSrc, 0, 4);
        mOfferText = Bitmap.createBitmap(mOfferText, 0, 0, mTextViewWidth, mTextViewHeight, mMatrix2, false);

      return mOfferText;
  }

  // Once complete, see if ImageView is still around and set bitmap.
  @Override
  protected void onPostExecute(Bitmap bitmap) {
      if (imageViewReference != null && bitmap != null) {
          final ImageView imageView = imageViewReference.get();
          if (imageView != null) {

                progressBar.setVisibility(View.GONE);

              imageView.setImageBitmap(bitmap);
          }
      }
  }
}

这篇关于Android的:内存从图纸缓存创建和扭曲后的位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆