久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

如何在不創建新位圖的情況下擁有圓形、中心裁

How to have a circular, center-cropped imageView, without creating a new bitmap?(如何在不創建新位圖的情況下擁有圓形、中心裁剪的 imageView?)
本文介紹了如何在不創建新位圖的情況下擁有圓形、中心裁剪的 imageView?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

注意:我知道有很多關于此的問題和存儲庫,但似乎沒有一個適合我嘗試實現的目標.

Note: I know there are a lot of questions and repositories about this, but none seems to fit what I try to achieve.

給定任何縱橫比的位圖,我希望將其設置為 ImageView 的內容(僅使用可繪制對象,不擴展 ImageView),以便內容將被中心裁剪,但形狀一個圓圈.

Given a bitmap of any aspect-ratio, I wish to set it as the content of an ImageView (using a drawable only, without extending the ImageView), so that the content will be center-cropped, and yet in the shape of a circle.

所有這些都使用最少的內存,因為有時圖像可能非常大.我不想為此創建一個全新的位圖.內容已經存在...

All of this, with minimal memory usage, because the images could be quite large sometimes. I do not want to create a whole new Bitmap just for this. The content is already there...

我發現的所有解決方案都缺少我所寫的內容之一:有些沒有居中裁剪,有些假設圖像是方形的,有些從給定的位圖創建一個新的位圖...

All solutions I've found lack one of the things I've written: some do not center-crop, some assume the image is square-shaped, some create a new bitmap from the given bitmap...

除了嘗試各種存儲庫之外,我還嘗試了 本教程,我嘗試針對非正方形縱橫比的情況進行修復,但失敗了.

Other than trying various repositories, I've tried this tutorial, and I tried to fix it for the case of non-square aspect ratios, but I've failed.

這是它的代碼,以防網站關閉:

Here's its code, in case the website will get closed:

public class RoundImage extends Drawable {
      private final Bitmap mBitmap;
      private final Paint mPaint;
      private final RectF mRectF;
      private final int mBitmapWidth;
      private final int mBitmapHeight;

      public RoundImage(Bitmap bitmap) {
            mBitmap = bitmap;
            mRectF = new RectF();
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mPaint.setShader(shader);

            mBitmapWidth = mBitmap.getWidth();
            mBitmapHeight = mBitmap.getHeight();
      }

      @Override
      public void draw(Canvas canvas) {
            canvas.drawOval(mRectF, mPaint);
      }

      @Override
      protected void onBoundsChange(Rect bounds) {
            super.onBoundsChange(bounds);
            mRectF.set(bounds);
      }

      @Override
      public void setAlpha(int alpha) {
            if (mPaint.getAlpha() != alpha) {
                  mPaint.setAlpha(alpha);
                  invalidateSelf();
            }
      }

      @Override
      public void setColorFilter(ColorFilter cf) {
            mPaint.setColorFilter(cf);
      }

      @Override
      public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
      }

      @Override
      public int getIntrinsicWidth() {
            return mBitmapWidth;
      }

      @Override
      public int getIntrinsicHeight() {
            return mBitmapHeight;
      }

      public void setAntiAlias(boolean aa) {
            mPaint.setAntiAlias(aa);
            invalidateSelf();
      }

      @Override
      public void setFilterBitmap(boolean filter) {
            mPaint.setFilterBitmap(filter);
            invalidateSelf();
      }

      @Override
      public void setDither(boolean dither) {
            mPaint.setDither(dither);
            invalidateSelf();
      }

      public Bitmap getBitmap() {
            return mBitmap;
      }

}

我找到了一個非常好的解決方案(這里) 完全符合我的需要,除了它在 ImageView 本身中使用它,而不是創建一個可繪制對象.這意味著我不能將它設置為例如視圖的背景.

A very good solution I've found (here) does exactly what I need, except it uses it all in the ImageView itself, instead of creating a drawable. This means that I can't set it, for example, as the background of a view.

我怎樣才能做到這一點?

How can I achieve this?

這是當前代碼,因為我想添加邊框,它也有這個代碼:

this is the current code, and as I wanted to add border, it also has this code for it:

public class SimpleRoundedDrawable extends BitmapDrawable {
    private final Path p = new Path();
    private final Paint mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public SimpleRoundedDrawable(final Resources res, final Bitmap bitmap) {
        super(res, bitmap);
        mBorderPaint.setStyle(Paint.Style.STROKE);
    }

    public SimpleRoundedDrawable setBorder(float borderWidth, @ColorInt int borderColor) {
        mBorderPaint.setStrokeWidth(borderWidth);
        mBorderPaint.setColor(borderColor);
        invalidateSelf();
        return this;
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        p.rewind();
        p.addCircle(bounds.width() / 2,
                bounds.height() / 2,
                Math.min(bounds.width(), bounds.height()) / 2,
                Path.Direction.CW);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.clipPath(p);
        super.draw(canvas);
        final float width = getBounds().width(), height = getBounds().height();
        canvas.drawCircle(width / 2, height / 2, Math.min(width, height) / 2, mBorderPaint);
    }
}

我希望事情應該是這樣運作的.

I hope this is how things should really work.

似乎該解決方案僅適用于特定的 Android 版本,因為它不適用于 Android 4.2.2.相反,它顯示了一個正方形的圖像.

It seems that the solution works only from specific Android version, as it doesn't work on Android 4.2.2. Instead, it shows a squared image.

似乎上述解決方案也比使用 BitmapShader 效率低得多(鏈接 這里).知道如何在可繪制對象中而不是在自定義的 ImageView 中使用它真的很棒

it seems that the above solution is also much less efficient than using BitmapShader (Link here). It would be really great to know how to use it within a drawable instead of within a customized ImageView

--這是以下解決方案的當前修改版本.我希望它對某些人有用:

-- Here's the current modified version of the below solutions. I hope it will be handy for some people:

public class SimpleRoundedDrawable extends Drawable {
    final Paint mMaskPaint = new Paint(Paint.ANTI_ALIAS_FLAG), mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Bitmap mBitmap;
    int mSide;
    float mRadius;

    public SimpleRoundedDrawable() {
        this(null);
    }

    public SimpleRoundedDrawable(Bitmap bitmap) {
        this(bitmap, 0, 0);
    }

    public SimpleRoundedDrawable(Bitmap bitmap, float width, @ColorInt int color) {
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBitmap = bitmap;
        mSide = mBitmap == null ? 0 : Math.min(bitmap.getWidth(), bitmap.getHeight());
        mBorderPaint.setStrokeWidth(width);
        mBorderPaint.setColor(color);
    }

    public SimpleRoundedDrawable setBitmap(final Bitmap bitmap) {
        mBitmap = bitmap;
        mSide = Math.min(bitmap.getWidth(), bitmap.getHeight());
        invalidateSelf();
        return this;
    }

    public SimpleRoundedDrawable setBorder(float width, @ColorInt int color) {
        mBorderPaint.setStrokeWidth(width);
        mBorderPaint.setColor(color);
        invalidateSelf();
        return this;
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        if (mBitmap == null)
            return;
        Matrix matrix = new Matrix();
        RectF src = new RectF(0, 0, mSide, mSide);
        src.offset((mBitmap.getWidth() - mSide) / 2f, (mBitmap.getHeight() - mSide) / 2f);
        RectF dst = new RectF(bounds);
        final float strokeWidth = mBorderPaint.getStrokeWidth();
        if (strokeWidth > 0)
            dst.inset(strokeWidth, strokeWidth);
        matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
        Shader shader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        shader.setLocalMatrix(matrix);
        mMaskPaint.setShader(shader);
        matrix.mapRect(src);
        mRadius = src.width() / 2f;
    }

    @Override
    public void draw(Canvas canvas) {
        Rect b = getBounds();
        if (mBitmap != null)
            canvas.drawCircle(b.exactCenterX(), b.exactCenterY(), mRadius, mMaskPaint);
        final float strokeWidth = mBorderPaint.getStrokeWidth();
        if (strokeWidth > 0)
            canvas.drawCircle(b.exactCenterX(), b.exactCenterY(), mRadius + strokeWidth / 2, mBorderPaint);
    }

    @Override
    public void setAlpha(int alpha) {
        mMaskPaint.setAlpha(alpha);
        invalidateSelf();
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mMaskPaint.setColorFilter(cf);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

推薦答案

試試這個極簡的自定義 Drawable 并修改它以滿足您的需求:

try this minimalist custom Drawable and modify it to meet your needs:

class D extends Drawable {
    Bitmap bitmap;
    Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    int side;
    float radius;

    public D(Bitmap wrappedBitmap) {
        bitmap = wrappedBitmap;
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(16);
        borderPaint.setColor(0xcc220088);
        side = Math.min(bitmap.getWidth(), bitmap.getHeight());
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        Matrix matrix = new Matrix();
        RectF src = new RectF(0, 0, side, side);
        src.offset((bitmap.getWidth() - side) / 2f, (bitmap.getHeight() - side) / 2f);
        RectF dst = new RectF(bounds);
        dst.inset(borderPaint.getStrokeWidth(), borderPaint.getStrokeWidth());
        matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);

        Shader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        shader.setLocalMatrix(matrix);
        maskPaint.setShader(shader);
        matrix.mapRect(src);
        radius = src.width() / 2f;
    }

    @Override
    public void draw(Canvas canvas) {
        Rect b = getBounds();
        canvas.drawCircle(b.exactCenterX(), b.exactCenterY(), radius, maskPaint);
        canvas.drawCircle(b.exactCenterX(), b.exactCenterY(), radius + borderPaint.getStrokeWidth() / 2, borderPaint);
    }

    @Override public void setAlpha(int alpha) {}
    @Override public void setColorFilter(ColorFilter cf) {}
    @Override public int getOpacity() {return PixelFormat.TRANSLUCENT;}
}

這篇關于如何在不創建新位圖的情況下擁有圓形、中心裁剪的 imageView?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

EditText: Disable Paste/Replace menu pop-up on Text Selection Handler click event(EditText:禁用文本選擇處理程序單擊事件上的粘貼/替換菜單彈出)
Multiline EditText with Done SoftInput Action Label on 2.3(2.3 上帶有完成 SoftInput 操作標簽的多行 EditText)
How to detect the swipe left or Right in Android?(如何在 Android 中檢測向左或向右滑動?)
Prevent dialog dismissal on screen rotation in Android(防止在Android中的屏幕旋轉對話框解除)
How do I handle ImeOptions#39; done button click?(如何處理 ImeOptions 的完成按鈕點擊?)
How do you set EditText to only accept numeric values in Android?(您如何將 EditText 設置為僅接受 Android 中的數值?)
主站蜘蛛池模板: 天天射av | 婷久久| 特黄a级片 | 欧美精品入口蜜桃 | 91亚洲国产成人久久精品麻豆 | 久草久草久草 | 日韩免费观看 | 欧美精品在线播放 | 色爽| 99热99| 婷婷av在线 | 免费av一区二区三区 | 欧美日韩不卡 | 久久综合99 | 国产高清免费视频 | 久久成人免费视频 | 秋霞一区二区 | 91插插插插插 | 中国极品少妇xxxx做受 | 久久精品一区二区三区不卡牛牛 | 久久综合av | www.狠狠操.com | 国产区一区二区 | 午夜在线免费视频 | 国产一级免费 | 解开岳的丰满奶罩bd | 99精品热 | 国产日韩在线视频 | 免费特级毛片 | 精品伊人久久 | 九色精品 | 国产在线欧美 | 国产精品久久久久久久久久久久午夜片 | 国内自拍偷拍 | 日本乱轮视频 | 日本免费网站 | 国产日韩综合 | 国产成人一区二区 | 成人三级小说 | 高清一区二区三区 | 国产999视频|