You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何在Canvas上绘制Squircle(圆角方形)图形

Solution: Convert Circle to Squircle on Android Canvas

Got it! Let's convert your circle-drawing logic to render a squircle instead—this shape sits neatly between a square and circle, with smooth, rounded corners that don't have the sharp transition of a regular rounded rectangle.

First, a quick recap: a squircle is defined by the equation (x^n + y^n = r^n) (where (n > 2); (n=4) gives the classic squircle shape). Android's Canvas doesn't have a built-in drawSquircle method, but we can build one using either a compatible Path with Bézier curves (works on all Android versions) or the newer Android 13+ API (cleaner, more accurate).


1. Compatible Implementation (All Android Versions)

This uses Bézier curves to approximate a squircle. You can adjust the control point factor to tweak how "square" or "round" the shape looks.

private static Bitmap makeIcon(int size, int color, Bitmap icon) {
    final Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(output);
    final Paint paint = new Paint();
    
    // Configure paint for smooth rendering
    paint.setAntiAlias(true);
    paint.setColor(color);
    canvas.drawARGB(0, 0, 0, 0); // Clear the canvas
    
    // Build the squircle path using Bézier curves
    Path squirclePath = new Path();
    float centerX = size / 2f;
    float centerY = size / 2f;
    float radius = size / 2f;
    
    // Control point factor: adjust this to change squareness (0.4-0.6 works well)
    float squarenessFactor = 0.5f;
    float offsetX = radius * squarenessFactor;
    float offsetY = radius * (1 - squarenessFactor);
    
    // Draw the squircle path
    squirclePath.moveTo(centerX, centerY - radius);
    squirclePath.cubicTo(centerX + offsetX, centerY - radius, 
                        centerX + radius, centerY - offsetY, 
                        centerX + radius, centerY);
    squirclePath.cubicTo(centerX + radius, centerY + offsetX, 
                        centerX + offsetX, centerY + radius, 
                        centerX, centerY + radius);
    squirclePath.cubicTo(centerX - offsetX, centerY + radius, 
                        centerX - radius, centerY + offsetX, 
                        centerX - radius, centerY);
    squirclePath.cubicTo(centerX - radius, centerY - offsetY, 
                        centerX - offsetX, centerY - radius, 
                        centerX, centerY - radius);
    squirclePath.close();
    
    // Draw the squircle
    canvas.drawPath(squirclePath, paint);
    
    // Draw the icon (centered on the squircle)
    if (icon != null) {
        float iconSize = size * 0.6f; // Adjust icon size relative to squircle
        float left = centerX - (iconSize / 2f);
        float top = centerY - (iconSize / 2f);
        canvas.drawBitmap(icon, left, top, paint);
    }
    
    return output;
}

Key Notes:

  • squarenessFactor: Values closer to 0 make the shape more circular; values closer to 1 make it more square. Stick to 0.4-0.6 for a classic squircle.
  • We replaced the original drawCircle call with drawPath using our custom squircle path.
  • The icon drawing logic is preserved and adjusted to center the icon on the squircle.

2. Simplified Implementation (Android 13+, API 33+)

Android 13 introduced Path.addSquircle(), which lets you draw a perfect squircle with a single method call. Use this if you don't need to support older versions.

import android.os.Build;
import androidx.annotation.RequiresApi;

@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
private static Bitmap makeIconApi33(int size, int color, Bitmap icon) {
    final Bitmap output = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(output);
    final Paint paint = new Paint();
    
    paint.setAntiAlias(true);
    paint.setColor(color);
    canvas.drawARGB(0, 0, 0, 0);
    
    float centerX = size / 2f;
    float centerY = size / 2f;
    float radius = size / 2f;
    float squareness = 0.5f; // 0 = circle, 1 = square
    
    // Build squircle path with the native API
    Path squirclePath = new Path();
    squirclePath.addSquircle(centerX, centerY, radius, squareness);
    
    canvas.drawPath(squirclePath, paint);
    
    // Draw centered icon
    if (icon != null) {
        float iconSize = size * 0.6f;
        float left = centerX - (iconSize / 2f);
        float top = centerY - (iconSize / 2f);
        canvas.drawBitmap(icon, left, top, paint);
    }
    
    return output;
}

Key Notes:

  • squareness parameter: Directly controls the shape—0 gives a perfect circle, 1 gives a square, and 0.5 gives a balanced squircle.
  • This method is more accurate than the Bézier approximation and requires less code.

内容的提问来源于stack exchange,提问作者fahmy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:50:01