【问题标题】:How to rotate a drawable with anti-aliasing enabled如何在启用抗锯齿的情况下旋转可绘制对象
【发布时间】:2010-06-08 23:30:36
【问题描述】:

我需要将 ImageView 旋转几度。我通过子类化 ImageView 并重载 onDraw()

来做到这一点
@Override
protected void onDraw(Canvas canvas) {
    canvas.save();
    canvas.scale(0.92f,0.92f);
    canvas.translate(14, 0);
    canvas.rotate(1,0,0);
    super.onDraw(canvas);
    canvas.restore();
}

问题是生成的图像显示了一堆锯齿。

http://img.skitch.com/20100608-gmdy4sexsm1c71di9rgiktdjhu.png

如何对需要旋转的 ImageView 进行抗锯齿处理以消除锯齿?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: android image rotation imageview


    【解决方案1】:

    如果您知道您的 Drawable 是 BitmapDrawable,您可以在位图的 Paint 中使用抗锯齿来执行以下操作:

    /**
     * Not as full featured as ImageView.onDraw().  Does not handle 
     * drawables other than BitmapDrawable, crop to padding, or other adjustments.
     */
    @Override
    protected void onDraw(Canvas canvas) {
        final Drawable d = getDrawable();
    
        if( d!=null && d instanceof BitmapDrawable && ((BitmapDrawable)d).getBitmap()!=null ) {
            final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
            final int paddingLeft = getPaddingLeft();
            final int paddingTop = getPaddingTop();
    
            canvas.save();
    
            // do my rotation and other adjustments
            canvas.scale(0.92f,0.92f);
            canvas.rotate(1,0,0);
    
            if( paddingLeft!=0 )
                canvas.translate(paddingLeft,0);
    
            if( paddingTop!=0 )
                canvas.translate(0,paddingTop);
    
            canvas.drawBitmap( ((BitmapDrawable)d).getBitmap(),0,0,p );
            canvas.restore();
        }
    }
    

    【讨论】:

      【解决方案2】:

      将 antialias 和 filterBitmap 设置为绘制位图的油漆。 我遇到了类似的问题,这对我有用:

      Paint bitmapPaint = new Paint();
      bitmapPaint.setAntiAlias(true);
      bitmapPaint.setFilterBitmap(true);
      

      【讨论】:

        【解决方案3】:

        我做了以下工作来让它工作:

        AndroidManifest.xml 中我启用了硬件加速<application android:hardwareAccelerated="true">

        我没有使用自定义绘制方法,而是将父视图的图层类型更改为启用了抗锯齿的硬件加速,并添加了我的子视图,如下所示:

        Paint layerPaint =  new Paint();
        layerPaint.setAntiAlias(true);
        layerPaint.setFilterBitmap(true);
        layerPaint.setDither(true);
        
        RelativeLayout parentLayout = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.myLayout, null);
        parentLayout.setLayerType(View.LAYER_TYPE_HARDWARE, layerPaint);
        
        parentLayout.addView(myChildView);
        

        我必须补充一点,使用这种方法时不能禁用剪辑。

        【讨论】:

          【解决方案4】:

          这种旋转只解决了一部分问题 - 锯齿状边缘,但图像反而变得怪异。

          我只找到了一种解决方案: 在 ondraw 或 dispatch draw 方法中

                  Bitmap bmp = ((BitmapDrawable)image.getDrawable()).getBitmap();
              double scale = (0.0+bmp.getWidth()+40.0)/getWidth();
              if (scale > 1){
                  bmp = Bitmap.createScaledBitmap(bmp, getWidth()-40, (int) (bmp.getHeight()/scale), true);
              }
          
              canvas.drawColor(Color.TRANSPARENT); 
              canvas.save();
          
              canvas.translate(20, yShift);
          
              int left = borderSize;
              int top = borderSize;
              int right = bmp.getWidth() - borderSize;
              int bottom = bmp.getHeight() - borderSize;
          
              if(showText){
                  mPaint.setColor(Color.WHITE);
                  canvas.rotate(getAngel());
                  canvas.drawRect(left, top, right, bottom, mPaint);
          
                  canvas.translate(0,0);
                  textFrame.draw(canvas);
              }else{
                  // rotaed bitmap 
                  mMatrix.setRotate(getAngel());
          
                  // draw bitmap after creation of new rotated bitmap from rotated matrix
                  canvas.drawBitmap(Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mMatrix, true)
                             , 0, 0, mPaint);
              }
              canvas.restore();       
          

          【讨论】:

            【解决方案5】:

            @Primoz990 的解决方案对我有用 :) 我还启用了抖动,所以我在旋转时移除锯齿状边缘的最终代码是这样的:

            Paint bitmapPaint =  new Paint();
            bitmapPaint.setAntiAlias(true);
            bitmapPaint.setFilterBitmap(true);
            bitmapPaint.setDither(true);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-11-26
              • 1970-01-01
              • 1970-01-01
              • 2010-12-19
              • 1970-01-01
              • 1970-01-01
              • 2020-10-21
              • 1970-01-01
              相关资源
              最近更新 更多