macOS 开发 - NSImge格式转换/压缩(CIImage/CGImageRef/NSData)

news/2024/3/29 22:57:16/文章来源:https://blog.csdn.net/lovechris00/article/details/81077949

文章目录

  • 格式转换
    • CGImageRef转NSImage
    • NSImage转CGImageRef
    • NSImage转CIImage
    • NSView 转 NSImage
  • 格式 jpg&png
  • 尺寸
  • 压缩
    • 将图片按照比例压缩
    • 将图片压缩到指定大小(KB)
  • demos
    • 修改图片尺寸并保存
    • 1、将指定路径图片,按照比例压缩,并保存
    • 2、组合图片


格式转换

需要导入头文件

 #import <QuartzCore/CIFilter.h>

CGImageRef转NSImage

#pragma mark -  CGImageRef转NSImage
- (NSImage *)getNSImageWithCGImageRef:(CGImageRef)imageRef{NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);CGContextRef imageContext = nil;NSImage* newImage = nil;imageRect.size.height = CGImageGetHeight(imageRef);imageRect.size.width = CGImageGetWidth(imageRef);// Create a new image to receive the Quartz image data.newImage = [[NSImage alloc] initWithSize:imageRect.size];[newImage lockFocus];// Get the Quartz context and draw.imageContext = (CGContextRef)[[NSGraphicsContext currentContext]graphicsPort];CGContextDrawImage(imageContext, *(CGRect*)&imageRect, imageRef);[newImage unlockFocus];return newImage;}

NSImage转CGImageRef

#pragma mark -  NSImage转CGImageRef
- (CGImageRef)getCGImageRefWithNSImage:(NSImage *)image{NSData * imageData = [image TIFFRepresentation];CGImageRef imageRef = nil;if(imageData){CGImageSourceRef imageSource =CGImageSourceCreateWithData((CFDataRef)imageData,  NULL);imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);}return imageRef;
}

NSImage转CIImage

#pragma mark -  NSImage转CIImage
- (void)getCIImageWithNSImage:(NSImage *)myImage{// convert NSImage to bitmap
//    NSImage * myImage  = [self currentImage];NSData  * tiffData = [myImage TIFFRepresentation];NSBitmapImageRep * bitmap;bitmap = [NSBitmapImageRep imageRepWithData:tiffData];// create CIImage from bitmapCIImage * ciImage = [[CIImage alloc] initWithBitmapImageRep:bitmap];// create affine transform to flip CIImageNSAffineTransform *affineTransform = [NSAffineTransform transform];[affineTransform translateXBy:0 yBy:128];[affineTransform scaleXBy:1 yBy:-1];// create CIFilter with embedded affine transformCIFilter *transform = [CIFilter filterWithName:@"CIAffineTransform"];[transform setValue:ciImage forKey:@"inputImage"];[transform setValue:affineTransform forKey:@"inputTransform"];// get the new CIImage, flipped and ready to serveCIImage * result = [transform valueForKey:@"outputImage"];// draw to view[result drawAtPoint: NSMakePoint ( 0,0 )fromRect: NSMakeRect  ( 0,0,128,128 )operation: NSCompositeSourceOverfraction: 1.0];// cleanup
//    [ciImage release];
}

NSView 转 NSImage

#pragma mark - NSView 转 NSImage
- (void)getNSImageWithNSView:(NSView *)zwView{[zwView lockFocus];//zwView为继承NSView类的一个对象NSImage *image = [[NSImage alloc] initWithData:[zwView dataWithPDFInsideRect:[zwView bounds]]];[zwView unlockFocus];[image lockFocus];//先设置 下面一个实例NSBitmapImageRep *bits = [[NSBitmapImageRep alloc]initWithFocusedViewRect:[zwView frame]];[image unlockFocus];//再设置后面要用到得 props属性NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:0] forKey:NSImageCompressionFactor];//之后 转化为NSData 以便存到文件中NSData *imageData = [bits representationUsingType:NSPNGFileType properties:imageProps];//设定好文件路径后进行存储就ok了[imageData writeToFile:[[[NSString alloc] initWithFormat:@"~/Documents/test%d.jpg",1] stringByExpandingTildeInPath]atomically:YES];    //保存的文件路径一定要是绝对路径,相对路径不行
}

格式 jpg&png

保存图片为png

#pragma mark - 保存图片为png
- (void)saveImage:(NSImage *)img asPngToPath:(NSString *)path{NSData *imageData = [img TIFFRepresentation];NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];//    [imageRep setSize:NSMakeSize(50, 50)]; //没用?//pngNSData *imgData0 = [imageRep representationUsingType:NSPNGFileType properties:nil];[imgData0 writeToFile:path atomically:YES];}

保存图片为jpg
注意,保存到本地的话,需要关闭沙盒。

 #pragma mark - 保存图片为jpg- (void)saveImage:(NSImage *)img asjpgToPath:(NSString *)path{NSData *imageData = [img TIFFRepresentation];NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];[imageRep setSize:NSMakeSize(50, 50)]; //没用?//pngNSData *imgData0 = [imageRep representationUsingType:NSPNGFileType properties:nil];NSData *imageData1 = [imageRep representationUsingType:NSJPEGFileType properties:nil];[imageData1 writeToFile:path atomically:YES];}

#pragma mark - 保存图片到本地
/*NSJPEGFileTypeNSPNGFileType*/
+ (void)saveImage:(NSImage *)imgasType:(NSBitmapImageFileType)storageTypetoPath:(NSString *)path{NSData *imageData = [img TIFFRepresentation];NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];NSData *imageData1 = [imageRep representationUsingType:storageType properties:nil];[imageData1 writeToFile:path atomically:YES];
}

尺寸

修改图片尺寸

#pragma mark - 修改图片尺寸
- (NSImage *)resizeImage:(NSImage*)sourceImagesize:(NSSize)size
{NSRect targetFrame = NSMakeRect(0, 0, size.width, size.height);NSImage* targetImage = nil;NSImageRep *sourceImageRep =[sourceImage bestRepresentationForRect:targetFramecontext:nilhints:nil];targetImage = [[NSImage alloc] initWithSize:size];[targetImage lockFocus];[sourceImageRep drawInRect: targetFrame];[targetImage unlockFocus];return targetImage;
}

压缩

将图片按照比例压缩

#pragma mark - 将图片按照比例压缩
//rate 压缩比0.1~1.0之间
- (NSData *)getCompressImageDataWithImg:(NSImage *)imgrate:(CGFloat)rate{NSData *imgDt = [img TIFFRepresentation];if (!imgDt) {return nil;}NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imgDt];NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:rate] forKey:NSImageCompressionFactor];imgDt = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];return imgDt;}

将图片压缩到指定大小(KB)

#pragma mark - 将图片压缩到指定大小(KB)
- (NSData *)getCompressImgData:(NSData *)imgDatatoAimKB:(NSInteger)aimKB
{if (!imgData) {return nil;}NSData *data =  [self getCompressImgDataWithData:imgData rate:0.8];CGFloat m = 0.1;CGFloat n = 1.0;while ((unsigned long)data.length > aimKB*1024) {n = n - m;//压缩前unsigned long datalenght = data.length;//压缩后data =  [self getCompressImgDataWithData:imgData rate:n];if (datalenght==data.length) {NSLog(@"无法继续压缩 - 数据大小:%lu , 压缩比率:%f",(unsigned long)data.length/1024,n);break;}NSLog(@"数据大小:%lu , 压缩比率:%f",(unsigned long)data.length/1024,n);}NSLog(@"数据最终大小:%lu",(unsigned long)data.length/1024);return data;
}#pragma mark - 将图片按照比例压缩
//rate 压缩比0.1~1.0之间
- (NSData *)getCompressImgDataWithData:(NSData *)imgDatarate:(CGFloat)rate{if (!imgData) {return nil;}NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imgData];NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:rate] forKey:NSImageCompressionFactor];imgData = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];return imgData;}

demos


修改图片尺寸并保存

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {self.imgPath = @"/Users/administrator/Desktop/cat.jpg";NSImage *img = [[NSImage alloc]initWithContentsOfFile:self.imgPath];NSImage *resizeImg = [self resizeImage:img size:NSMakeSize(30, 30)];[self saveImage:resizeImg asjpgToPath:@"/Users/administrator/Desktop/cat_r.jpg"];
}#pragma mark - 修改图片尺寸
- (NSImage *)resizeImage:(NSImage*)sourceImagesize:(NSSize)size
{NSRect targetFrame = NSMakeRect(0, 0, size.width, size.height);NSImage* targetImage = nil;NSImageRep *sourceImageRep =[sourceImage bestRepresentationForRect:targetFramecontext:nilhints:nil];targetImage = [[NSImage alloc] initWithSize:size];[targetImage lockFocus];[sourceImageRep drawInRect: targetFrame];[targetImage unlockFocus];return targetImage;
}

1、将指定路径图片,按照比例压缩,并保存

#pragma mark - 将图片按照比例压缩
//rate 压缩比0.1~1.0之间
- (NSData *)getCompressImage:(NSImage *)imgrate:(CGFloat)rateoutPath:(NSString *)outPath{NSData *imgDt = [img TIFFRepresentation];if (!imgDt) {return nil;}NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imgDt];NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:rate] forKey:NSImageCompressionFactor];imgDt = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];int ret = [imgDt writeToFile:outPath atomically:YES];if (ret>0) {NSLog(@"success - outPath : %@ , rate : %f,%ld",outPath,rate,imgDt.length);}else{printf("FAILURE!\n");}return imgDt;
}- (void)compressImage{NSString *imgPath = @"/Users/administrator/Desktop/cat.jpg";NSString *imgPath1 = @"/Users/administrator/Desktop/cat1.jpg";NSString *imgPath2 = @"/Users/administrator/Desktop/cat2.jpg";NSImage *img = [[NSImage alloc]initWithContentsOfFile:imgPath];[self getCompressImage:img rate:0.1 outPath:imgPath1];[self getCompressImage:img rate:0.5 outPath:imgPath2];}

2、组合图片

- (void)jointImage{  NSMutableArray *imgArray = [NSMutableArray array];for (int i = 1; i < 6; i++) {NSString *imgPath = [NSString stringWithFormat:@"/Users/administrator/Desktop/图片/%d.jpg",i];NSImage *img = [[NSImage alloc]initWithContentsOfFile:imgPath];[imgArray addObject:img];}[self jointImage:imgArray];}- (NSImage *)jointImage:(NSArray *)imgArray{CGFloat imgW = 0;CGFloat imgH = 0;for (NSImage *img in imgArray) {if (img) {imgW += img.size.width;if (imgH < img.size.height) {imgH = img.size.height;}}}NSLog(@"size : %@",NSStringFromSize(NSMakeSize(imgW, imgH)));NSImage *togetherImg = [[NSImage alloc]initWithSize:NSMakeSize(imgW, imgH)];[togetherImg lockFocus];CGContextRef imgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];CGFloat imgX = 0;for (NSImage *img in imgArray) {CGImageRef imageRef = [self getCGImageRefFromNSImage:img];CGContextDrawImage(imgContext, NSMakeRect(imgX, 0, img.size.width, img.size.height), imageRef);imgX += img.size.width;NSLog(@"rect : %@",NSStringFromRect(NSMakeRect(imgX, 0, img.size.width, img.size.height)));}[togetherImg unlockFocus];return togetherImg;}

伊织 2018-07-17

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Crafting interpreters 中文翻译,持续修正

本书在线地址 http://craftinginterpreters.com/ 感谢作者 作者用近 4 年的时间持续创作和改进本书&#xff0c;并把其 Web 版本公开在网上。这本纸质书于今年 7 月出版&#xff0c;立刻在 Hacker News 等网络媒介上引起关注和讨论。 书中作者首先定义了一个动态类型的语言 …

棋牌类游戏测试用例怎么写?我敢打赌你绝对不知道

目录 一&#xff0e;登陆 二&#xff0e;大厅 三&#xff0e;小游戏 四&#xff0e;银行功能 五&#xff0e;其他按钮 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;配套学习资料和视频教学 一&#xff0e;登陆 1&#xff0e…

使用拦截器实现登录状态检测(以及在注册拦截器类时要使用ioc中的拦截器类)

拦截器 preHandler(HttpServletRequest request, HttpServletResponse response, Object handler) 方法在请求处理之前被调用。该方法在 Interceptor 类中最先执行&#xff0c;用来进行一些前置初始化操作或是对当前请求做预处理&#xff0c;也可以进行一些判断来决定请求是否…

【MyBatis】源码学习 04 - 从 MapperMethod 简单分析一条 SQL 的映射操作流程

文章目录前言参考目录学习笔记1、测试代码说明2、binding 包的主要功能3、获取 Mapper 接口实例过程4、SQL 语句执行流程4.1、方法调用器4.2、MapperMethod 绑定方法4.2.1、SqlCommand4.2.2、MethodSignature4.3、MapperMethod#execute前言 本文内容对应的是书本第 13 章的内容…

循环、函数、对象——js基础练习

目录 一、循环练习 1.1 取款机案例 1.2 九九乘法表 1.3 根据数据生成柱形图 1.4 冒泡排序 1.6综合大练习 二、函数 2.1 转换时间案例 三、对象 1. 遍历数组对象 2. 猜数字游戏 3. 生成随机颜色 4. 学成在线页面渲染案例 一、循环练习 1.1 取款机案例 // 准备一个…

电商项目之Feign与Dubbo技术选型

文章目录1 问题背景2 前言3 思路4 Feign与Dubbo的区别5 总结6 真实案例1 问题背景 电商项目&#xff0c;B端以consul作为注册中心。重构了一个营销服务&#xff0c;以Nacos作为注册中心。B端需要调用营销服务。关于远程调用框架&#xff0c;营销服务用了Dubbo&#xff0c;而B端…

黑马程序员-Linux网络编程-01

目录 课程链接 协议 分层模型 网络传输数据封装流程 以太网帧和ARP请求 IP协议 TCP协议 BS与CS模型对比 套接字 网络字节序 IP地址转换函数 sockaddr地址结构 socket模型创建流程 socket()和bind() listen()和accept()​ 课程链接 03-协议_哔哩哔哩_bilibili 协…

java并发笔记

文章目录HashMapput方法resize方法ConcurrentHashMapput方法initTable方法sizectl代表什么&#xff1a;扩容计数器ConcurrentHashMap的读操作会阻塞嘛AQS唤醒线程时&#xff0c;AQS为什么从后往前遍历&#xff1f;AQS为什么要有一个虚拟的head节点AQS为什么用双向链表&#xff…

万字C语言学习笔记,带你学C带你飞(四)

文章目录单链表typedef1、基础typedef2、进阶typedef共用体枚举类型1、声明枚举类型2、定义枚举变量位域位操作文件的写入与写出C语言学习笔记&#xff0c;记录所学&#xff0c;便于复习。 由于篇幅过大&#xff0c;考虑到观感&#xff0c;准备分多篇记录。学习视频链接&#x…

Vue3.x使用Echarts绘制世界地图并进行定点

Vue3.x使用Echarts绘制世界地图并进行定点 一、需求 绘制世界地图并根据返回经纬度数据进行定点将定点数据展示在世界地图内 二、解决 绘制世界地图&#xff0c;利用Echarts图表组件时间&#xff0c;需要世界地图Geojson数据的可以在资源中下载世界地图Geojson数据-Javascr…

2022FALL嵌入式大纲

Jamslade 部分内容有遗漏&#xff0c;可结合 超文本 2022FALL《嵌入式系统原理》期末复习笔记 一起观看 文章目录嵌入式系统片上系统实时系统硬实时系统软实时系统伪指令DMA传输波特率单/半双/全双工通信&#xff1b;对齐/非对齐访问地址译码代码临界区RISCBIOSUARTSPII2CWDTRO…

2.5|shell简介|Linux支持的网络协议|Linux的网络服务

shell简介shell是一种具备特殊功能的程序&#xff0c;它是介于使用者和Unix/Linux操作系统内核间的一个接口。操作计算机需要通过命令&#xff08;command&#xff09;或是程序&#xff08;program&#xff09;&#xff1b;程序需要编译器&#xff08;compiler&#xff09;将程…

东南大学研究生英语18-19秋试卷解析

写在前面 作者&#xff1a;夏日 博客地址&#xff1a;https://blog.csdn.net/zss192 本文为东南大学研究生英语上学期18-19年期末试卷解析&#xff0c;答案来源于 ChatGPT International Conference 单选题 1.A presenter is supposed to do the following in an introdu…

【数据结构趣味多】八大排序

目录 1.直接插入排序 基本思想 代码实现&#xff1a; 直接插入排序的特性总结&#xff1a; 2.希尔排序 基本思想 代码实现 &#xff08;递归实现&#xff09; 希尔排序的特性总结 3.直接选择排序 基本思想 代码实现&#xff1a; 直接选择排序的特性总结 4.堆排序 …

Springboot 全局异常处理类

全局异常处理 在开发过程中&#xff0c;不管是Dao、Servie、Controller,层都有可能发生异常&#xff0c;对于异常处理&#xff0c;通常是try&#xff0d;catch或者直接throw&#xff0c;这会让try&#xff0d;catch的代码在代码中任意出现&#xff0c;系统的代码耦合度高&…

深入Spring底层透析bean生命周期及循环引用的醍醐灌顶篇

目录前言一.Bean的生命周期1.1 Bean的实例化阶段1.2 Bean的初始化阶段&#xff08;重点&#xff09;1.3 Bean的完成阶段二.循环引用问题(面试常问题&#xff09;三.Spring的三级缓存&#xff08;重点来了&#xff09;四.完整的Spring IoC整体总结前言 本篇是接着bean的创建基本…

2023/02/21 事件循环-eventloop 宏任务 微任务 讲解

1 JS是单线程 js是单线程的。也就是说&#xff0c;同一个时间只能做一件事。作为浏览器脚本语言&#xff0c;与它的用途有关。JavaScript的主要用途是和用户互动&#xff0c;以及操作DOM&#xff0c;这决定了它只能是单线程。 js是单线程的。也就是说&#xff0c;同一个时间只…

非常优秀的网站设计案例,设计师必备

厚积才能薄发&#xff0c;一个优秀的设计师的天性一定是想要获得更多网站设计灵感&#xff0c;擅于为新项目寻找创意切入点、搜索设计参考资源、最新的设计趋势。今天为大家带来了一组免费可商用的网站设计案例&#xff0c;通过这些网站设计案例&#xff0c;你可以获得&#xf…

CF707C Pythagorean Triples 题解

CF707C Pythagorean Triples 题解题目链接字面描述题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2样例 #3样例输入 #3样例输出 #3样例 #4样例输入 #4样例输出 #4样例 #5样例输入 #5样例输出 #5提示思路代码实现题目 链接 http…

华为OD机试 - 最短耗时(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…