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

如何创建带有可点击区域的图片?基于SkiaSharp的实现

基于Xamarin Forms + SkiaSharp实现带可点击区域的图片

1. 配置依赖

先给你的Xamarin Forms项目安装以下NuGet包:

  • SkiaSharp
  • SkiaSharp.Views.Forms
  • 对应平台的原生资产包:SkiaSharp.NativeAssets.Android、SkiaSharp.NativeAssets.iOS(根据你需要支持的平台选择)

2. 构建界面布局

在XAML中添加SKCanvasView作为SkiaSharp的渲染容器,并绑定触摸与渲染事件:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="YourNamespace.ClickableImagePage">
    <skia:SKCanvasView x:Name="CanvasView" 
                       PaintSurface="OnCanvasViewPaintSurface"
                       Touch="OnCanvasViewTouch"/>
</ContentPage>

3. 定义可点击区域与基础数据

在后台代码中,准备背景图片并定义可点击区域集合。这里以矩形区域(SKRect)为例,你也可以用SKPath实现不规则区域:

using SkiaSharp;
using SkiaSharp.Views.Forms;
using System.Collections.Generic;
using Xamarin.Forms;

namespace YourNamespace
{
    public partial class ClickableImagePage : ContentPage
    {
        // 存储可点击区域:键为区域,值为区域对应的操作标识
        private readonly Dictionary<SKRect, string> _clickableAreas = new Dictionary<SKRect, string>();
        private SKBitmap _backgroundImage;

        public ClickableImagePage()
        {
            InitializeComponent();
            LoadBackgroundImage();
            SetupClickableAreas();
        }

        // 加载背景图片(示例从项目资源加载,替换为你的图片路径)
        private void LoadBackgroundImage()
        {
            using var stream = typeof(ClickableImagePage).Assembly.GetManifestResourceStream("YourNamespace.Images.background.png");
            _backgroundImage = SKBitmap.Decode(stream);
        }

        // 定义可点击区域,根据你的实际图片坐标调整参数
        private void SetupClickableAreas()
        {
            _clickableAreas.Add(new SKRect(50, 50, 150, 150), "区域1");
            _clickableAreas.Add(new SKRect(200, 100, 300, 200), "区域2");
            _clickableAreas.Add(new SKRect(100, 250, 250, 350), "区域3");
        }

4. 渲染图片与交互区域

实现PaintSurface事件,绘制背景图片,调试阶段可以画出可点击区域的边框(上线时可移除):

private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;
            canvas.Clear();

            // 缩放图片适配画布大小
            var scaleX = e.Info.Width / (float)_backgroundImage.Width;
            var scaleY = e.Info.Height / (float)_backgroundImage.Height;
            var scale = System.Math.Min(scaleX, scaleY);
            var drawRect = new SKRect(0, 0, _backgroundImage.Width * scale, _backgroundImage.Height * scale);
            canvas.DrawBitmap(_backgroundImage, drawRect);

            // 调试用:绘制可点击区域的红色边框(上线时注释或删除)
            using var borderPaint = new SKPaint
            {
                Color = SKColors.Red,
                Style = SKPaintStyle.Stroke,
                StrokeWidth = 2
            };
            foreach (var area in _clickableAreas.Keys)
            {
                var scaledArea = new SKRect(area.Left * scale, area.Top * scale, area.Right * scale, area.Bottom * scale);
                canvas.DrawRect(scaledArea, borderPaint);
            }
        }

5. 处理触摸点击事件

实现Touch事件,将触摸坐标转换为原始图片坐标,判断是否命中可点击区域:

private void OnCanvasViewTouch(object sender, SKTouchEventArgs e)
        {
            if (e.ActionType == SKTouchAction.Pressed)
            {
                var touchPoint = e.Location;
                var scaleX = CanvasView.CanvasSize.Width / (float)_backgroundImage.Width;
                var scaleY = CanvasView.CanvasSize.Height / (float)_backgroundImage.Height;
                var scale = System.Math.Min(scaleX, scaleY);

                // 将画布触摸坐标转换为原始图片坐标
                var originalPoint = new SKPoint(touchPoint.X / scale, touchPoint.Y / scale);

                // 遍历区域判断命中
                foreach (var (area, actionTag) in _clickableAreas)
                {
                    if (area.Contains(originalPoint))
                    {
                        // 触发对应操作,示例:弹出提示
                        DisplayAlert("点击触发", $"你点击了{actionTag}", "确定");
                        break;
                    }
                }
            }
            e.Handled = true;
        }
    }
}

关键细节说明

  • 坐标转换:因为图片会根据画布缩放,必须将触摸的画布坐标转换为原始图片坐标,才能准确匹配预定义的可点击区域。
  • 不规则区域支持:如果需要不规则可点击区域,把SKRect替换为SKPath,使用SKPath.Contains(originalPoint)判断命中即可。
  • 图片加载:除了资源加载,也支持从本地文件或网络异步加载图片,注意处理加载完成后的重绘逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 23:15:26