“This is the third day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021.”

Tooth uncle tutorial is easy to understand

Results show

The environment

Mi 11 Pro Android version: 11 Autojs version: 9.0.11 Picture shape: square

7 ways to display a round head

Type 1: Use the ShapeableImageView control

Note: The Material version requires a minimum of 1.2.0, since the ShapeableImageView control was added in 1.2.0

"ui"; importClass(android.view.ViewOutlineProvider); importClass(android.content.res.ColorStateList); importClass(com.google.android.material.shape.RelativeCornerSize); importClass(com.google.android.material.shape.AbsoluteCornerSize); importClass(com.google.android.material.shape.CornerFamily); importClass(com.google.android.material.shape.ShapeAppearanceModel); ui.layout( <vertical> <com.google.android.material.imageview.ShapeableImageView android:id="@+id/image" android:layout_width="110dp" android:layout_height="110dp" android:padding="0dp" margin="20dp" app:strokeColor="#ff0000"  android:src="file://./yashu.png" /> </vertical> ); imgView = ui.image; imgView.shapeAppearanceModel = ShapeAppearanceModel.builder().setAllCornerSizes(ShapeAppearanceModel.PILL).build();Copy the code
Second: Use setOutlineProvider to set the outline of the view

By default, all views are rectangular. Although you can give a view a circular image with a background that displays circular content on the screen, the size of the view is actually rectangular and the image is actually rectangular, except that the area outside the circle is transparent.

To solve this problem, the view added a new description that specifies the shape of the content to display. This is called the outline

"ui"; importClass(android.view.ViewOutlineProvider); ui.layout( <vertical> <img android:id="@+id/image" android:layout_width="110dp" android:layout_height="110dp" android:padding="0dp" margin="20dp" app:strokeColor="#ff0000" android:src="file://./yashu.png" /> </vertical> ); let img = $images.read("./yashu.png"); imgView = ui.image; ui.post(function () { viewOutlineProvider = new ViewOutlineProvider({ getOutline: function (view, outline) { outline.setRoundRect(0, 0, imgView.width, imgView.height, imgView.width / 2); }}); imgView.setOutlineProvider(viewOutlineProvider); imgView.setClipToOutline(true); }); events.on("exit", function () { img.recycle(); });Copy the code
The third: use card control

Set cardCornerRadius to half the width of the control

ui.layout(
  <vertical margin="100">
    <card android:layout_width="100dp" android:layout_height="100dp" cardCornerRadius="50dp">
      <img
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:padding="0dp"
        app:strokeColor="#ff0000"
        android:src="file://./yashu.png"
      />
    </card>
  </vertical>
);
Copy the code
Type 4: Sets the cornerRadius property of the IMG control

The width of the control is the same as that of the control. Note that the unit size of the control is not the default dp. Dp and PX can be converted to each other

ui.layout( <vertical margin="100"> <img id="image" src="file://./yashu.png" w="100" h="100" radius="30" scaleType="centerCrop" /> </vertical> ); imageView = ui.image; const scale = context.getResources().getDisplayMetrics().density; Const dp2px = (dp) => math.floor (dp * scale + 0.5); ui.post(function () { imageView.attr("cornerRadius", dp2px(100)); // imageView.invalidate(); });Copy the code
Fifth: when drawing a control, crop the display area to a circle,

Use setBackgroundDrawable to set the background for the control. When the DRAW event occurs, clipping the drawboard to a circle can rewrite the draw method, which is one of the most important content in the custom control.

ui.layout( <vertical margin="100"> <View id="image" w="100" h="100" /> </vertical> ); imageView = ui.image; let img = $images.read("./yashu.png"); bitmap = img.getBitmap(); const scale = context.getResources().getDisplayMetrics().density; Const dp2px = (dp) => math.floor (dp * scale + 0.5); ui.post(function () { var drawable = new android.graphics.drawable.Drawable({ draw: function (canvas) { let paint = new Paint(); var path = new Path(); path.addCircle(imageView.getWidth() / 2, imageView.getHeight() / 2, imageView.getWidth() / 2, Path.Direction.CCW); canvas.clipPath(path); dst = new Rect(0, 0, imageView.getWidth(), imageView.getHeight()); DrawBitmap (bitmap, NULL, DST, paint); }}); imageView.setBackgroundDrawable(drawable); });Copy the code
Type 6: Use BitmapShader

Add the image to shader and set the brush shader. The brush draws a circle on the palette

"ui"; importClass(android.graphics.Rect); importClass(android.graphics.PorterDuffXfermode); importClass(android.graphics.Path); importClass(android.graphics.Xfermode); importClass(android.graphics.Paint); importClass(android.graphics.Bitmap); importClass(android.graphics.BitmapShader); importClass(android.graphics.Shader); importClass(android.graphics.Matrix); importClass(android.graphics.PorterDuff); ui.layout( <vertical margin="100"> <View id="image" w="100" h="100" /> </vertical> ); imageView = ui.image; let img = $images.read("./yashu.png"); bitmap = img.getBitmap(); const scale = context.getResources().getDisplayMetrics().density; Const dp2px = (dp) => math.floor (dp * scale + 0.5); ui.post(function () { var drawable = new android.graphics.drawable.Drawable({ draw: function (canvas) { let paint = new Paint(); radius = imageView.getWidth() / 2; bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); MScale = (radius * 2.0)/math.min (bitmap.getheight (), bitmap.getwidth ())); matrix = new Matrix(); matrix.setScale(mScale, mScale); bitmapShader.setLocalMatrix(matrix); paint.setShader(bitmapShader); canvas.drawCircle(radius, radius, radius, paint); }}); imageView.setBackgroundDrawable(drawable); }); events.on("exit", function () { img.recycle(); });Copy the code
Type 7: use PorterDuffXfermode

When instantiating canvas, add an empty image as instance parameter, draw a circle, and set overlay mode to SRC_IN.

Then draw a picture, and then save the canvas palette content as a picture, set the picture to the IMG control

"ui"; importClass(android.graphics.Rect); importClass(android.graphics.RectF); importClass(android.graphics.PorterDuffXfermode); importClass(android.graphics.Path); importClass(android.graphics.Xfermode); importClass(android.graphics.Paint); importClass(android.graphics.Bitmap); importClass(android.graphics.PorterDuff); ui.layout( <vertical margin="100"> <img id="image" w="100" h="100" /> </vertical> ); imageView = ui.image; let img = $images.read("./yashu.png"); bitmap = img.getBitmap(); const scale = context.getResources().getDisplayMetrics().density; Const dp2px = (dp) => math.floor (dp * scale + 0.5); let newImg; ui.post(function () { let paint = new Paint(); let mBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); let canvas = new Canvas(mBitmap); let rect = new Rect(0, 0, img.getWidth(), img.getWidth()); let rectF = new RectF(rect); let ratio = 2; canvas.drawRoundRect(rectF, img.getWidth() / ratio, img.getWidth() / ratio, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); let dst = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); DrawBitmap (bitmap, NULL, DST, paint); newImg = canvas.toImage(); imageView.setImageBitmap(newImg.bitmap); }); events.on("exit", function () { img.recycle(); newImg && newImg.recycle(); });Copy the code

Quotes.

Ideas are the most important, other Baidu, Bing, StackOverflow, Github, Android docs, AutoJS docs, and last but not least, ask in the group

The statement

This tutorial is intended for learning purposes only and is not intended for any other use

Wechat official account tooth Uncle tutorial