使用CGImageRef创建图片及实现图片区域裁剪(附源码)

news2024/12/24 2:45:01

一 CGImageRef和UIImage的互相转化

CGImageRef 是一个结构体指针,通过CGImageRef可以获得UIImage的所有参数,比如像素宽高、颜色通道位深、像素点位深、像素点字节排列及读取顺序等信息,CGImageRef与UIImage的互相转化如下:

UIImage 转 CGImageRef

    UIImage *image = [UIImage imageNamed:@"testImg"];
    CGImageRef imageRef = image.CGImage;

CGImageRef 转 UIImage

    CGImageRef imageRef = [UIImage imageNamed:@"testImg"].CGImage;
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];

切记每次使用CGImageRef一定要记得释放,否则会造成内存泄露,释放方式也很简单,如下所示:

    CGImageRelease(imageRef); 

二 CGImageRef的创建方法

使用png数据源创建

使用方法

CGImageCreateWithPNGDataProvider(CGDataProviderRef cg_nullable source, const CGFloat * __nullable decode, bool shouldInterpolate, CGColorRenderingIntent intent)

使用示例:

    NSString *path = [[NSBundle mainBundle] pathForResource:@"bundle8Bit" ofType:@".png"];
    NSData *bundleImgData = [NSData dataWithContentsOfFile:path];
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)bundleImgData);
    CGImageRef imageRef = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
    UIImage *image = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    
    self.imageV.image = image;

使用jpeg数据源创建

使用方法

CGImageCreateWithJPEGDataProvider(CGDataProviderRef cg_nullable source, const CGFloat * __nullable decode, bool shouldInterpolate, CGColorRenderingIntent intent)

使用示例:

    NSString *path = [[NSBundle mainBundle] pathForResource:@"houst" ofType:@".jpg"];
    NSData *bundleImgData = [NSData dataWithContentsOfFile:path];
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)bundleImgData);
    CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
    UIImage *image = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    
    self.imageV.image = image;

使用矩阵数据源创建

使用矩阵数据源创建图片是最灵活的一种方法,基本上可以完全满足我们所有的定制化需求,可以在实现对图片进行像素级的改动,使用方法名

CGImageCreate(size_t width, size_t height,size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGColorSpaceRef cg_nullable space, CGBitmapInfo bitmapInfo,CGDataProviderRef cg_nullable provider,const CGFloat * __nullable decode, bool shouldInterpolate,CGColorRenderingIntent intent)

参数解析如下:
size_t width 图片宽度(像素级别)
size_t height 图片高度(像素级别)
size_t bitsPerComponent 每个像素通道位深(bit数量)
size_t bitsPerPixel 每个像素点位深(bit数量)
size_t bytesPerRow 每行像素空间大小(单位 字节)
CGColorSpaceRef cg_nullable space 颜色空间
CGBitmapInfo bitmapInfo 像素排列及读取顺序
CGDataProviderRef cg_nullable provider 数据提供源
const CGFloat * __nullable decode 解码arrr 一般传入null 保持源数据
bool shouldInterpolate 是否使用差值来平滑过渡图像
CGColorRenderingIntent intent 从一个颜色空间map到另一个颜色空间的方式

使用方式

//创建一个宽2000像素 高3000像素 每通道8bit 一共三通道(无alpha通道) 使用rgb颜色空间 的一张纯红色的图片
    size_t imageWidth = 2000;
    size_t imageHeight = 3000;
    size_t bitsPerComponent = 8;
    size_t bitsPerPixel = 24;
    size_t bytesPerRow = imageWidth * bitsPerPixel / 8;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGImageByteOrderDefault;

    //创建纯红色数据源
    int byteIndex = 0;
    unsigned char *rawData = (unsigned char*) malloc(imageWidth * imageHeight * 3);
    for (int i = 0; i < imageHeight; i ++) {
        for (int j = 0; j < imageWidth; j ++) {
            rawData[byteIndex ++] = 255; //red通道
            rawData[byteIndex ++] = 0;  //green通道
            rawData[byteIndex ++] = 0;  //blue通道
        }
    }
    CGDataProviderRef dataProviderRef = CGDataProviderCreateWithData(NULL,
                                                                     rawData,
                                                                     imageWidth*imageHeight*3,
                                                                     NULL);

    CGImageRef imageRef = CGImageCreate(imageWidth,
                                        imageHeight,
                                        bitsPerComponent,
                                        bitsPerPixel,
                                        bytesPerRow,
                                        colorSpaceRef,
                                        bitmapInfo,
                                        dataProviderRef,
                                        nil,
                                        NO,
                                        kCGRenderingIntentDefault);
    UIImage *image = [UIImage imageWithCGImage:imageRef];
    CGColorSpaceRelease(colorSpaceRef);
    CGDataProviderRelease(dataProviderRef);
    CGImageRelease(imageRef);
    
    self.imageV.image = image;

创建结果
在这里插入图片描述
输出图片信息核对:

    size_t bitsPerComponentCheck = CGImageGetBitsPerComponent(imageRef);
    printf("每个通道占用的位数:%zu\n",bitsPerComponentCheck);
    size_t bitsPerPixelCheck = CGImageGetBitsPerPixel(imageRef);
    printf("每个像素占用的位数:%zu",bitsPerPixelCheck);
输出结果:
每个通道占用的位数:8
每个像素占用的位数:24

跟我们创建的参数一致

三 使用CGImageRef对图片进行裁剪

方法 CGImageCreateWithImageInRect(CGImageRef cg_nullable image, CGRect rect)

使用方法几示例如下

    NSString *path = [[NSBundle mainBundle] pathForResource:@"bundle8Bit" ofType:@".png"];
    NSData *bundleImgData = [NSData dataWithContentsOfFile:path];
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)bundleImgData);
    CGImageRef imageRef = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
    CGImageRef clipImageRef = CGImageCreateWithImageInRect(imageRef, CGRectMake(0, 0, 100, 200));
    UIImage *image = [UIImage imageWithCGImage:clipImageRef];
    self.imageV.image = image;

以图片左上角为顶点,裁剪出来像素宽100,高200的图片区域
裁剪原图:
在这里插入图片描述
裁剪出来的图片:
在这里插入图片描述

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

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

相关文章

GEE:计算每个斑块(超像素、对象)内的特征/统计值

作者:CSDN @ _养乐多_ 在遥感图像分析中,斑块(或对象)是指具有相似像素值的区域,通常代表地物或景观要素。通过计算斑块的特征,我们可以获得关于这些区域的有用信息,从而进行更深入的分析和研究。在本文中,我们将介绍如何使用Google Earth Engine(GEE)平台计算每个斑…

深入理解Java虚拟机:JVM高级特性与最佳实践-总结-7

深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践-总结-7 类文件结构概述无关性的基石 虚拟机类加载机制概述类加载的时机 类文件结构 代码编译的结果从本地机器码转变为字节码&#xff0c;是存储格式发展的一小步&#xff0c;却是编程语言发展的一大步 概述 我们写的程…

JavaScript实现计算1-10之间的乘积的数的代码

以下为实现计算1-10之间的乘积的数的程序代码和运行截图 目录 前言 一、实现计算1-10之间的乘积 1.1 运行流程及思想 1.2 代码段 1.3 JavaScript语句代码 1.4 运行截图 前言 1.若有选择&#xff0c;您可以在目录里进行快速查找&#xff1b; 2.本博文代码可以根据题目要…

chatgpt赋能Python-python3_7怎么换行

Python 3.7 的换行方法详解 Python 是一种广泛应用的高级编程语言&#xff0c;它具有简单易学&#xff0c;功能强大&#xff0c;可移植性好等特点&#xff0c;深受全球开发者的喜爱。其中&#xff0c;每个程序员在编写代码时最常用的是打印输出函数&#xff0c;而其中换行更是…

[c++] enum和string相互转换

enum和string相互转换 简介满足的需求code使用方法可优化点 参考链接 简介 原理还是很朴素的方法&#xff0c;只是用宏省略了重复代码&#xff0c;降低维护难度&#xff1b; // enum to string std::string enum2Str(Color c) {switch(c){case RED: return "RED";c…

Pytorch从零开始实现Vision Transformer (from scratch)

Pytorch从零开始实现Vision Transformer 前言一、Vision Transformer架构介绍1. Patch Embedding2. Multi-Head Attention3. Transformer BlockFeed Forward 二、预备知识1. Einsum2. Einops 三、Vision Transformer代码实现0. 导入库1. Patch Embedding2. Residual & Norm…

Ethereum以太坊事件日志查询参数

目录 一、Ethereum事件日志查询参数二、需求三、实现四、其他 一、Ethereum事件日志查询参数 addresses&#xff1a;合约地址列表fromBlock&#xff1a;开始区块toBlock&#xff1a;结束区块topics&#xff1a;主题数组blockhash&#xff1a;区块哈希&#xff0c;优先级高于fr…

chatgpt赋能Python-python3_9_1怎么用

Python3.9.1是什么&#xff1f; Python是一种高级、动态、解释型语言&#xff0c;具有优雅简洁、易于学习和阅读、功能丰富的特点。Python 3.9.1是Python编程语言的一个版本&#xff0c;于2020年12月21日正式发布&#xff0c;是Python 3的最新稳定版本。它包含了许多新的特性、…

chatgpt赋能Python-python3_7降级3_6

Python 3.7降级3.6&#xff1a;为什么&#xff1f;如何做&#xff1f; 如果你是一个认真的Python开发者&#xff0c;你可能会对Python 3.7的某些改进感到兴奋。但是&#xff0c;在某些情况下&#xff0c;你可能需要将Python降级到3.6版本。在这篇文章中&#xff0c;我们将探讨…

网吧管理系统修正

文章目录 网吧管理系统修正1. 改动1&#xff1a;上机缴费2. 改动2&#xff1a;下机超时计费3. 改动3&#xff1a;注销强制下机操作4. 改动4&#xff1a;计费标准数据的获取与释放 网吧管理系统修正 Carry文件中&#xff0c;打开文件忘记关闭了&#xff0c;虽然C语言中不会报错…

【STM32G431RBTx】备战蓝桥杯嵌入式→决赛试题→第八届

文章目录 前言一、题目二、模块初始化三、代码实现interrupt.h:interrupt.c:main.h:main.c: 四、完成效果五、总结 前言 学习完了所有模块之后(LIS302考点取消了, 扩展板也找不到了&#xff0c;如果你能找到可能你不是在十四届省赛后买的扩展板), 跟省赛一样&#xff0c;先拿第…

这个屏幕录制太好用了!

哈喽&#xff0c;大家好&#xff01;今天给各位小伙伴测试了一屏幕录制的小工具——ApowerREC。它是一款专业同步录制屏幕画面及声音的录屏软件。界面简洁&#xff0c;操作简单&#xff0c;支持实时编辑屏幕录像、创建计划任务、录制摄像头高清视频等功能。废话不多说&#xff…

汇编九、直接地址与寄存器、ROM和RAM

1、直接地址与寄存器 1.1、A和ACC (1)A是没有地址的&#xff0c;可以当作寄存器使用。 (2)ACC是有地址的&#xff0c;地址为E0H(查数据手册)。 (3)如果使用压栈操作&#xff0c;要用ACC。因为ACC可当做直接地址。 (4)如果使用位操作&#xff0c;要用ACC。因为ACC可位寻址。…

总结855

学习目标&#xff1a; 月目标&#xff1a;5月&#xff08;张宇强化前10讲&#xff0c;背诵15篇短文&#xff0c;熟词僻义300词基础词&#xff09; 周目标&#xff1a;张宇强化前3讲并完成相应的习题并记录&#xff0c;英语背3篇文章并回诵 每日必复习&#xff08;5分钟&#…

chatgpt赋能Python-python3_9_2怎么安装

Python3.9.2的安装指南 Python是一种高级编程语言&#xff0c;广泛应用于各种领域&#xff0c;从数据科学到机器学习到Web应用程序。Python具有易学性和通用性&#xff0c;因此成为众多开发人员的首选语言。此篇文章将指导您如何安装Python3.9.2版本。 为什么选择Python3.9.2…

Packet Tracer – 对 VLAN 实施进行故障排除 – 方案 1

Packet Tracer – 对 VLAN 实施进行故障排除 – 方案 1 地址分配表 设备 接口 IP 地址 子网掩码 交换机端口 VLAN PC1 NIC 172.17.10.21 255.255.255.0 S2 F0/11 10 PC2 NIC 172.17.20.22 255.255.255.0 S2 F0/18 20 PC3 NIC 172.17.30.23 255.255.255.0…

一星期学mysql day2

文章目录 DQL&#xff08;数据查询语言&#xff09;基础查询条件查询聚合查询&#xff08;聚合函数&#xff09;分组查询注意事项 排序查询注意事项 分页查询注意事项 编写顺序DQL执行顺序 DCL 管理用户管理用户注意事项 权限控制注意事项 函数字符串函数数值函数日期函数流程函…

车辆管理系统的设计与实现

背景 4S店车辆系统&#xff0c;为用户随时随地查看4S店车辆信息提供了便捷的方法&#xff0c;更重要的是大大的简化了管理员管理4S店车辆信息的方式方法&#xff0c;更提供了其他想要了解4S店车辆信息及运作情况以及挑选方便快捷的可靠渠道。相比于传统的管理方法&#xff0c;…

chatgpt赋能Python-python3_8怎么安装numpy库

Python3.8怎么安装numpy库&#xff1f;一个详细的步骤指南 你是否想要在Python3.8中安装numpy库&#xff0c;但不知道如何开始&#xff1f;没问题&#xff0c;本篇文章将介绍Python3.8的numpy安装步骤。 什么是numpy&#xff1f; numpy是Python中的一个重要的数学计算库&…

chatgpt赋能Python-python3_7怎么保存

Python 3.7 - 新的保存方式 Python 语言是一种广泛使用的编程语言之一&#xff0c;它在数据分析、网络编程、科学计算等领域都得到了广泛的应用。Python 的一个新版本&#xff0c;Python 3.7&#xff0c;增加了一种新的保存方式&#xff0c;这种方式可以提高数据的保存效率&am…