在视图世界中,我们可以使用view.draw(画布(在画布上绘制视图(可能连接到位图(。但在写作中,我们如何才能做到这一点。
我们有一个draw修饰符,但它没有方法draw(canvas(
更新
我需要什么
我想通过将可组合函数包装在模糊可组合函数中来模糊它。假设xyz((是任意一个随机组合标签函数。
@Composable
fun xyz(){
// compose logic.
}
我想创造另一种乐趣,叫做Blur((。
@Composable
fun Blur(content: @Composable() -> Unit){
//Blur logic.
}
Blur可组合函数接受任何可组合函数(比如xyz(((作为输入并对其进行模糊处理。
我将如何实施它
我想我会采用与BlurView(视图模糊库(相同的方法。
- 模糊视图是一个框架布局
- 它模糊了内容
- BlurView首先创建内容的位图;模糊了它;然后绘制
- 用于创建内容位图的函数是
view.draw(canvas: Canvas)
为什么我需要这个
我想在compose中创建我的BlurView版本。我知道在创作中有一个Modifier.blur;但由于这只在api 31中得到支持(我想(,所以我不能在我的项目中使用它。
在Compose
中,有一个Canvas可组合函数可用于DrawScope
。你可以利用它来画画。
DrawScope具有drawImage
函数来获取ImageBitmap。正如你有位图需要转换使用Bitmap.asImageBitmap()
正如在另一个回复中所指出的,您可以创建一个使用画布的可组合文件,这将使您能够访问与常规View画布中相同的许多绘图方法。
@Composable
fun MyCanvasComposable(
data: List<Int>, //some example data to pass in
modifier: Modifier = Modifier
) {
Canvas() {
.. content here
}
}
在画布中,您将进入DrawScope,它将允许您像以前一样进行画布绘制。
我将添加一些示例,假设我们将绘图逻辑引入到扩展方法中。示例:
绘制一些文本
internal fun DrawScope.drawSomeText() {
//some logic here before drawing the text
drawContext.canvas.nativeCanvas.drawText(
[[your text]],
positionX,
positionY,
paint
)
}
绘制路径
internal fun DrawScope.plotXAxis(
//some custom rendering here followed by this method
drawPath(path, pathBrush, 0.5f)
}
为了将画布放在另一个布局上,您可以使用适当的布局修饰符调用MyCanvasComposable。
如果你想在画布上渲染其他可组合的东西,你可以把整个东西包在一个盒子里,然后在画布绘制之前或之后添加视图。
示例:
val myPainter = painterResource(id = R.drawable.src_image)
Box {
Image(
painter = myPainter
)
Canvas() {
.. content here ..
}
Text( "some text")
}
在上面的例子中,您也可以只调用MyCanvasComposable而不是Canvas((。
还请注意,图像将在画布之前渲染,文本则在画布之后渲染,也就是说在画布顶部。如果您想要从View函数或这里提到的RenderScript等方法中模糊Bitmap
,并在其上绘制地标或形状,您可以使用androidx.compose.ui.graphics.Canvas
代替androidx.compose.foundation.Canvas
val option = BitmapFactory.Options()
option.apply {
inPreferredConfig = Bitmap.Config.ARGB_8888
inMutable = true
}
val imageBitmap = RenderEffect.createBitmapEffect(Bitmap bitmap)
对于api 31-
private Bitmap blur(Bitmap original, float radius) {
Bitmap bitmap = Bitmap.createBitmap(
original.getWidth(), original.getHeight(),
Bitmap.Config.ARGB_8888);
RenderScript rs = RenderScript.create(this);
Allocation allocIn = Allocation.createFromBitmap(rs, original);
Allocation allocOut = Allocation.createFromBitmap(rs, bitmap);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(
rs, Element.U8_4(rs));
blur.setInput(allocIn);
blur.setRadius(radius);
blur.forEach(allocOut);
allocOut.copyTo(bitmap);
rs.destroy();
return bitmap;
}
我现在不在我的电脑上,当我有空的时候,我会添加它作为修改器。
// 🔥 This is a function that returns Canvas which can be used to draw on an
// ImageBitmap that was sent as param. ImageBitmap that returned can be
// be used to display on Image or can be saved to a physical file.
val canvas: androidx.compose.ui.graphics.Canvas = Canvas(imageBitmap)
val paint = remember {
Paint().apply {
style = PaintingStyle.Stroke
strokeWidth = 10f
color = Color(0xff29B6F6)
}
}
canvas.drawRect(0f, 0f, 200f, 200f, paint = paint)
canvas.drawCircle(
Offset(
imageBitmap.width / 2 - 75f,
imageBitmap.height / 2 + 75f
), 150.0f, paint
)
// This bitmap has image and the drawing from canvas
Image(bitmap = imageBitmap, contentDescription = null)