久久久久久久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 中的數值?)
主站蜘蛛池模板: 欧美综合一区二区 | 337p日本欧洲亚洲大胆精蜜臀 | 91精品久久久久久综合五月天 | www.青青草 | 在线观看亚洲欧美 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 久久神马| 91精品国产一区二区三区 | 黑人久久 | 祝你幸福电影在线观看 | 欧美精品一区二区三区蜜桃视频 | 羞羞的视频在线观看 | 色偷偷噜噜噜亚洲男人 | 欧美精品成人 | 激情 一区| 亚洲一区不卡在线 | 成人精品一区二区户外勾搭野战 | 精品一区电影 | 久久久久国 | 伊人激情网 | 中文字幕亚洲欧美日韩在线不卡 | 亚洲精品久久久久久一区二区 | 狠狠干天天干 | 成人在线精品视频 | 国产激情一区二区三区 | 婷婷五月色综合香五月 | 国产1区2区在线观看 | 亚洲国产欧美日韩 | 欧美视频二区 | 精品欧美一区二区在线观看视频 | 自拍偷拍中文字幕 | 欧美成人在线网站 | 国产亚洲一区二区三区在线观看 | 中文字幕第十页 | 精品国产乱码一区二区三区 | 中文字幕乱码一区二区三区 | 亚洲天堂一区 | 久久精品亚洲欧美日韩精品中文字幕 | 视频1区2区 | 怡红院免费的全部视频 | 欧美日韩精品一区二区三区四区 |