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

news2024/11/19 1:32:50

装扮功能系列:

  1. Swift 使用UIScrollerView 实现装扮功能(基础)
  2. Swift 使用UIScrollerView 实现装扮功能(拓展)
  3. 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思无邪愿与您一起在技术的道路上不断探索。如果您喜欢这篇文章,不妨留下您宝贵的赞!如果您对文章有任何疑问或建议,欢迎在评论区留言,我会第一时间处理,您的支持是我前行的动力,愿我们都能成为更好的自己!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1514743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ES分布式搜索-使用RestClient操作索引库

RestClient操作索引库 1、什么是RestClient&#xff1f; ES官方提供了各种不同语言的客户端&#xff0c;用来操作ES。这些客户端的本质就是组装DSL语句&#xff0c;通过http请求发送给ES。官方文档地址&#xff1a;Elasticsearch Clients官方文档 2、利用JavaRestClient实现…

软考高级:软件架构风格-闭环控制概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

Python 查找PDF中的指定文本并高亮显示

在处理大量PDF文档时&#xff0c;有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…

Java学习笔记(11)

面向对象进阶 Static 静态变量 所有对象一起共享&#xff0c;就用static修饰 不属于对象&#xff0c;属于类的 可以用 类名.静态变量 “”&#xff1b;赋值 但是 对象.静态变量也可以访问到内容 Static内存图 Student这个类的字节码文件加载到方法区&#xff0c;并在内…

企业计算机服务器中了eking勒索病毒怎么办?Eking勒索病毒解密工具流程

网络数据安全问题一直是众多企业关心的主要话题&#xff0c;网络在为企业提供便利的同时&#xff0c;也为企业数据安全带来未知的隐患。近日&#xff0c;云天数据恢复中心接到许多企业求助&#xff0c;企业的计算机服务器遭到了eking勒索病毒攻击导致企业计算机服务器系统瘫痪无…

操作系统——cpu、内存、缓存介绍

一、内存是什么 内存就是系统资源的代名词&#xff0c;它是其他硬件设备与 CPU 沟通的桥梁&#xff0c; 计算机中的所有程序都在内存中运行。其作用是暂时存放CPU的运算数据&#xff0c;以及与硬盘交换的数据。也是相当于CPU与硬盘沟通的桥梁。只要计算机在运行&#xff0c;CP…

YOLOv9实例分割教程|(一)训练教程

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、创建数据集及数据配置文件 创新一个文件夹存放分割数据集&#xff0c;包含一个images和labels文件夹。标签格式如下所示&#xff1a; 创新数据集…

Netty线程模型详解

文章目录 概述单Reactor单线程模型单Reactor多线程模型主从Reactor多线程模型 概述 Netty的线程模型采用了Reactor模式&#xff0c;即一个或多个EventLoop轮询各自的任务队列&#xff0c;当发现有任务时&#xff0c;就处理它们。Netty支持单线程模型、多线程模型和混合线程模型…

1、计划任务介绍

Windows计划任务介绍 1、含义&#xff1a; 简单点就是定时执行任务。 在许多场景下&#xff0c;我们定时执行一些任务。比如&#xff1a;定时拉取、备份文件&#xff0c;更新代码等等操作。 WinR打开运行框&#xff0c;输入&#xff1a;control schedtasks&#xff0c;就会…

SAR ADC系列4——比较器的Transient noise仿真--等效输入噪声

仿真出等效输入噪声 加一个快于实际工作的时钟频率&#xff1b;在输入端加一个DC的差&#xff08;比如一端是0.5VDD&#xff0c;另外一端加0.5VDD0.2MV)计算仿真时间内的correct counting number&#xff0c;比如时钟频率是200MHz&#xff0c;仿真时间是5us&#xff0c;那么应…

IMX8MM -- Yocto构建遇见的错误及解决方法:

IMX8MM Yocto构建遇见的错误及解决方法&#xff1a; 1 bison-3.0.4 error2 Opencv BB_NO_NETWORK Error &#xff1a;3 Yocto构建时出现U-boot 问题4 Yocto构建时出现Linux kernel编译问题5 wayland-native6 cross-localedef-native7 wayland-protocols8 mesa 硬件&#xff1a;…

[论文精读]Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection

论文网址&#xff1a;[2304.08876] 用于定向微小目标检测的动态粗到细学习 (arxiv.org) 论文代码&#xff1a;https://github.com/ChaselTsui/mmrotate-dcfl 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&…

android MMKV数据持久化缓存集合

前言 最近在使用mmkv缓存的时候 发现没有集合缓存 非常不方便 自己写一个方法 MMKV public class MmkvUtils {private MmkvUtils() {throw new UnsupportedOperationException("u cant instantiate me...");}public static void init() {MMKV.initialize(LeoUtils…

C语言从入门到熟悉------第三阶段

数组 什么是数组呢&#xff1f;顾名思义数组就是很多数的组合&#xff01;那么这些数有没有什么要求呢&#xff1f;是不是不管什么数组合在一起都是数组呢&#xff1f;第一&#xff0c;这些数的类型必须相同&#xff01;第二&#xff0c;这些数在内存中必须是连续存储的。也就…

力扣思路题:重复的子字符串

注意比较j与j-i是否相同 bool repeatedSubstringPattern(char* s) {int i;int nstrlen(s);bool flag;for(int i1;i<n/2;i){if(n%i0){flagtrue;}for(int ji;j<n;j){if(s[j]!s[j-i]){flagfalse;break;}}if(flagtrue){return true;}}return false; }

Python爬虫基础学习-互联网、HTTP与HTML

互联网或者叫国际网&#xff08;Internet&#xff09;&#xff0c;是指网络与网络之间所串连成的庞大网络&#xff0c;这些网络以一组标准的网络TCP/IP协议族相连&#xff0c;连接全世界几十亿个设备&#xff0c;形成逻辑上的单一巨大国际网络。它是由从地方到全球范围内几百万…

【算法】一类支持向量机OC-SVM(2)

【算法】一类支持向量机OC-SVM&#xff08;2&#xff09; 前言纠正内容数据集创建方式适应度函数 新增内容散点图示例模型散点图展示 前言 在上则博文【算法】一类支持向量机OC-SVM&#xff08;1&#xff09; 中&#xff0c;我们提及到了蜂群算法优化一类支持向量机超参数模型…

gpt-4-all模型中转实现

最近才完成这个功能&#xff0c;相信知道这个模型的人&#xff0c;应该已经熟悉了。这是我的中转&#xff1a;openai-api Chatbox配置如下&#xff1a; 模型测试&#xff1a; 1&#xff09;图片生成 2&#xff09;文件分析&#xff0c;链接读取&#xff1a;

WWW2024 | PromptMM:Prompt-Tuning增强的知识蒸馏助力多模态推荐系统

论文&#xff1a;https://arxiv.org/html/2402.17188v1 代码&#xff1a;https://github.com/HKUDS/PromptMM 研究动机 多模态推荐系统极大的便利了人们的生活,比如亚马逊和Netflix都是基于多模态内容进行推荐的。对于研究,人们也遵循工业界的趋势,进行modality-aware的用户…

初步了解序列化和反序列化

01什么是序列化和反序列化 序列化是将对象转化为字符串以便存储的一种方式。而反序列化恰好是序列化的逆过程&#xff0c;反序列化会将字符串转化为对象供程序使用。 常见的php系列化和反系列化方式主要有&#xff1a;serialize&#xff0c;unserialize&#xff1b;json_enco…