iOS 判断触摸位置是否在图片的透明区域

背景

在装扮功能中,一般都是长按使道具进入编辑状态,两个物品重叠一部分并且上面一个道具具有较大的透明区域时,明明想编辑的是下面一个道具,然而进入编辑状态的却是在上面的较大的一个道具。那么我们可以如何优化用户体验呢?可以通过判断触摸点的位置,如果是透明区域就不响应不进入编辑状态,从上到下遍历,直到找到非透明的道具然后将它设为编辑状态。
请添加图片描述

图片组成

图片的组成主要由像素(Pixels)和元数据(Metadata)两部分构成。

  1. 像素:图片是由一个个像素点组成的。每个像素代表图像中的一个小区域,并包含了该区域的颜色信息。常见的颜色模型是RGB(红绿蓝),每个像素的颜色由红、绿、蓝三个分量的数值来表示。每个分量的数值通常以8位无符号整数(0-255)的形式表示,可以通过不同的数值组合形成各种颜色。除了红、绿、蓝三个分量,每个像素还可以包含一个透明度分量。透明度分量用于表示像素的不透明度或透明度,决定了像素在图像中的可见程度。透明度值通常以8位无符号整数(0-255)表示,其中0表示完全透明,255表示完全不透明。
  2. 元数据:除了像素数据之外,图片还包含了一些描述图像属性和特征的元数据。元数据可以包括图像的尺寸、分辨率、创建日期、拍摄设备信息、拍摄参数、版权信息等。元数据提供了对图像的更多信息和上下文,使得图片的使用和管理更加方便和有意义。常见的图像文件格式如JPEG、PNG等都支持存储元数据。

分析和实现需求

当我们理解啦图片的基本构成后,我们的需求就可以理解成:判断当前触摸点在图片上对应的位置上的像素点,获取像素点的颜色信息中的透明度的值,透明度的值为0的话,就判定当前点击的位置是图片的透明区域,否则就是非透明区域。

一、位置转换
前提:图片是等比例缩放布局显示的
将当前触摸点的位置转换为图片上的位置。

  1. 获取触摸点位置
  2. 获取图片大小
  3. 根据控件坐标转换成图片坐标
       @objc func tapClick(_ gesture:UITapGestureRecognizer){
    
        //在图片控件中的位置
        let treePoint = gesture.location(in: treeImageV)
        print("treePoint:\(treePoint)")
        
        //真实图片上的位置
        let imageW = treeImageV.image?.size.width ?? 0
        let imageH = treeImageV.image?.size.height ?? 0
        let treeImagePointX = treePoint.x * imageW/treeImageV.yh_width
        let treeImagePointY = treePoint.y * imageH/treeImageV.yh_height
        
        let treeImagePoint = CGPoint(x: treeImagePointX, y: treeImagePointY)
        
        print("treeImagePoint:\(treeImagePoint)")
        
        
        if let treeImage = treeImageV.image, isPointTransparent(treeImagePoint, in: treeImage){
            print("当前点击的是treeImage的透明区域")
        }

    }

二、透明度
通过转换后的坐标,拿到当前坐标的像素点,然后再根据像素中的颜色信息判断是否透明

// 判断图像中指定位置是否透明
    func isPointTransparent(_ point: CGPoint, in image: UIImage) -> Bool {
        guard let cgImage = image.cgImage else {
            return false
        }
        
        let width = cgImage.width
        let height = cgImage.height
        
        let targetX = Int(point.x)
        let targetY = Int(point.y)
        
        // 检查目标点是否在图像范围内
        if targetX < 0 || targetX >= width || targetY < 0 || targetY >= height {
            return false
        }
        //获取图像的数据提供者
        guard let provider = cgImage.dataProvider else {
            return false
        }

        // 获取图像的数据并将其转换为字节数组
        guard let pixelData = provider.data, let data = CFDataGetBytePtr(pixelData) else {
            return false
        }
        //获取图像的alpha信息
        let alphaInfo = cgImage.alphaInfo
      
        let bytesPerPixel = cgImage.bitsPerPixel / 8
        let pixelOffset = (targetY * cgImage.bytesPerRow) + (targetX * bytesPerPixel)
        if alphaInfo == .none {
            // 对于没有透明度通道的图像,直接判断颜色通道是否为0
            return data[pixelOffset] == 0 && data[pixelOffset + 1] == 0 && data[pixelOffset + 2] == 0
        } else {
            // 对于有透明度通道的图像,判断透明度是否为0
            return data[pixelOffset + bytesPerPixel - 1] == 0
        }
    }

感谢您的阅读和参与,HH思无邪愿与您一起在技术的道路上不断探索。如果您喜欢这篇文章,不妨留下您宝贵的赞!如果您对文章有任何疑问或建议,欢迎在评论区留言,我会第一时间处理,您的支持是我前行的动力,愿我们都能成为更好的自己!

相关推荐

  1. 如何判断一个元素是否可视区域

    2024-03-11 03:50:01       7 阅读
  2. c++ 判断人脚位置是否合理

    2024-03-11 03:50:01       8 阅读
  3. 判断某个ip是否某个网段下

    2024-03-11 03:50:01       41 阅读
  4. ios 获取图片一部分区域

    2024-03-11 03:50:01       8 阅读
  5. iOS 更改button文字和图片位置

    2024-03-11 03:50:01       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-11 03:50:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-11 03:50:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-11 03:50:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-11 03:50:01       20 阅读

热门阅读

  1. Web前端_html5+css3

    2024-03-11 03:50:01       20 阅读
  2. TMGM中国官网平台合作的MT4交易软件MT5

    2024-03-11 03:50:01       23 阅读
  3. 服务器防火墙和安全组放开

    2024-03-11 03:50:01       22 阅读
  4. 线程池的执行流程

    2024-03-11 03:50:01       37 阅读
  5. SSL证书怎么开启?

    2024-03-11 03:50:01       21 阅读
  6. Python基础学习(9)迭代器/生成器

    2024-03-11 03:50:01       20 阅读
  7. SQL注入攻击 - 堆叠注入(Stacked Injection)

    2024-03-11 03:50:01       22 阅读
  8. python实现数据爬虫

    2024-03-11 03:50:01       25 阅读
  9. 唤起原生IOS和安卓Android app的方法

    2024-03-11 03:50:01       22 阅读
  10. 在C#中使用Linq

    2024-03-11 03:50:01       22 阅读
  11. 读取CSV数据并写入MySQL

    2024-03-11 03:50:01       23 阅读
  12. G1垃圾收集器

    2024-03-11 03:50:01       21 阅读