我有以下代码:
UIImage *originalImage;
CGImageRef cgImage = [originalImage CGImage];
Run Code Online (Sandbox Code Playgroud)
我知道CGImage是UIImage类的只读属性.是行吗?
CGImageRelease(cgImage)
Run Code Online (Sandbox Code Playgroud)
免费originalImage的记忆?
我正在追踪我的程序中的一个错误,如果我稍后尝试访问originalImage,这一行似乎是一个热门的候选人.
谢谢,斯特凡
在我创建以像素为中心的图像编辑器的实验中,我一直在尝试绘制精确的网格叠加,以帮助引导用户尝试访问某些像素.但是,我绘制的网格不是很均匀,尤其是尺寸较小的网格.对于每几个普通列,这是一个略大的列的常规模式,所以我认为这是一个舍入问题,但我在代码中看不到它.这是我的代码:
- (void)drawRect:(NSRect)dirtyRect
{
context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextAddRect(context, NSRectToCGRect(self.bounds));
CGContextSetRGBStrokeColor(context, 1.0f, 0.0f, 0.0f, 1.0f);
CGContextStrokePath(context);
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
CGContextSetShouldAntialias(context, NO);
if (image)
{
NSRect imageRect = NSZeroRect;
imageRect.size = CGImageGetSize([image CGImage]);
drawRect = [self bounds];
NSRect viewRect = drawRect;
CGFloat aspectRatio = imageRect.size.width / imageRect.size.height;
if (viewRect.size.width / viewRect.size.height <= aspectRatio)
{
drawRect.size.width = viewRect.size.width;
drawRect.size.height = imageRect.size.height * (viewRect.size.width / imageRect.size.width);
}
else
{
drawRect.size.height = viewRect.size.height;
drawRect.size.width = imageRect.size.width * (viewRect.size.height / imageRect.size.height);
}
drawRect.origin.x += (viewRect.size.width …Run Code Online (Sandbox Code Playgroud) 我在网上尝试了很多"解决方案",我发现的所有这些都有错误因此无法正常工作.我需要知道UIImage中像素的颜色.我怎样才能获得这些信息?
我试图从UIImage中裁剪一个区域以与GLKTextureLoader一起使用.我可以使用UIImage直接设置纹理,如下所示:
- (void)setTextureImage:(UIImage *)image
{
NSError *error;
texture = [GLKTextureLoader textureWithCGImage:image.CGImage options:nil error:&error];
if(error)
{
NSLog(@"Texture Error:%@", error);
} else {
self.textureCoordinates[0] = GLKVector2Make(1.0f, 1.0f);
self.textureCoordinates[1] = GLKVector2Make(1.0f, 0);
self.textureCoordinates[2] = GLKVector2Make(0, 0);
self.textureCoordinates[3] = GLKVector2Make(0, 1.0f);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试以这种方式裁剪图像:
- (void)setTextureImage:(UIImage *)image
{
NSError *error;
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, CGRectMake(0.0, 64.0f, 64.0f, 64.0f));
texture = [GLKTextureLoader textureWithCGImage:imageRef options:nil error:&error];
if(error)
{
NSLog(@"[SF] Texture Error:%@", error);
} else {
self.textureCoordinates[0] = GLKVector2Make(1.0f, 1.0f);
self.textureCoordinates[1] = GLKVector2Make(1.0f, 0);
self.textureCoordinates[2] = GLKVector2Make(0, …Run Code Online (Sandbox Code Playgroud) 我的崩溃只发生在4S(而不是3GS)上.我怀疑是因为@ 2x.基本上我得到原始字节的图像和操作.这是我的问题.
我加载了下面示例代码中提到的图像.最后,uiWidth应为2000,cgwidth应为2000.正确吗?(如果从相机胶卷加载图像,它仍然是真的吗?或者它的自动缩放和uiWidth将是4000?)
//test.jpg is 2000x 1500 pixels.
NSString *fileName = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"];
UIImage *image = [UIImage imageWithContentsOfFile:fileName];
int uiWidth = image.size.width;
CGImageRef cgimg = image.CGImage;
int cgWidth = CGImageGetWidth(cgimg);
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助.
我尝试将与我的 MAC 连接的所有显示器的屏幕截图显示为一张图片。我知道,如果每个显示器的屏幕截图都保存到不同的图片,我该怎么做,但这不是我想要的。我找到了函数CGGetDisplaysWithRect,但我的解决方案不起作用,因为输出图片是空的。我预计,函数 CGDisplayCreateImageForRect (*displays, rect) 的问题,因为第一个参数必须是 CGDirectDisplayID 类型,而不是 CGDirectDisplayID*。但是我找不到可以用一些 CGDirectDisplayID 对象创建一张图片的函数。
请帮帮我!!!
#include <stdio.h>
#include <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
CGDisplayCount displayCount;
CGDirectDisplayID displays[32];
memset(&displays, 0, 32);
CGImageRef image[32];
CGRect rect = CGRectNull;
//grab the active displays
if (CGGetActiveDisplayList(32, displays, &displayCount) != kCGErrorSuccess)
{
printf("Error occured: %s\n", strerror(errno));
}
//go through the list
for (int i = 0; i < displayCount; i++)
{
if (CGDisplayMirrorsDisplay(displays[i]) != kCGNullDirectDisplay)
{
continue;
}
//return the smallest …Run Code Online (Sandbox Code Playgroud) 我正在使用 swift 定位 Mac OS 导出动画 gif,它可以工作,但我设置的属性没有被应用。我已经设置了我的属性,当我记录它们时,它们显示如下:
{
HasGlobalColorMap = 1;
LoopCount = 0;
}
Run Code Online (Sandbox Code Playgroud)
在循环中,我将每个帧添加到目的地:
CGImageDestinationAddImage(destination, cgGif, gifProperties as CFDictionaryRef)
Run Code Online (Sandbox Code Playgroud)
然后在循环之后,我尝试再次设置属性并最终确定目的地:
CGImageDestinationSetProperties(destination, gifProperties as CFDictionaryRef)
if (!CGImageDestinationFinalize(destination)) {
NSLog("failed to finalize image destination")
}
Run Code Online (Sandbox Code Playgroud)
但是,生成的图像未设置为循环。为什么会这样?
我有一个带有填充颜色的 CAShapeLayer,并且想在这个形状的中心添加一个图标:
var shape = CAShapeLayer()
shape.fillColor = UIColor(white: 0.90, alpha: 1).CGColor
var image = UIImage(named: "some_image")
shape.contents = image?.CGImage
Run Code Online (Sandbox Code Playgroud)
这段代码可以编译并显示灰色形状 - 但没有图像。:(
我查看了这些帖子,但我无法像他们那样投射 CGImage。
在 CALayer 中添加 UIImage并使用普通 CALayer 显示图像或 UIImage
还有其他方法吗?或者 id 转换的解决方法?
完整代码:
视图控制器.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet var menuView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(animated: Bool) {
let menu: CircularMenu = CircularMenu(frame: menuView.bounds, numberOfMenuItems: …Run Code Online (Sandbox Code Playgroud) 我正在考虑优化从 CGImage 获取像素数据的例程。目前这样做的方式(非常低效)是创建一个新的 CGContext,将 CGImage 绘制到上下文中,然后从上下文中获取数据。
我有以下优化的例程来处理这个问题:
CGImageRef imageRef = image.CGImage;
uint8_t *pixelData = NULL;
CGDataProviderRef imageDataProvider = CGImageGetDataProvider(imageRef);
CFDataRef imageData = CGDataProviderCopyData(imageDataProvider);
pixelData = (uint8_t *)malloc(CFDataGetLength(imageData));
CFDataGetBytes(imageData, CFRangeMake(0, CFDataGetLength(imageData)), pixelData);
CFRelease(imageData);
Run Code Online (Sandbox Code Playgroud)
这几乎有效。通过查看和比较两种方法得到的像素数据的hex dump,我发现在上面的例子中,每6360个字节就有8个字节是0。否则,数据是相同的。例如

这是与未优化版本的比较:

在 0 的 8 个字节之后,正确的像素数据继续。有谁知道为什么会这样?
更新:这是我正在优化的例程(剪下的代码只是获取大小信息和其他不重要的东西;相关位是返回的像素数据):
CGContextRef context = NULL;
CGImageRef imageRef = image.CGImage;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst;
// ... SNIP ...
context = CGBitmapContextCreate(...);
CGColorSpaceRelease(colorSpace);
// ... SNIP ...
CGContextDrawImage(context, rect, imageRef);
uint8_t *pixelData = (uint8_t *)CGBitmapContextGetData(context);
CGContextRelease(context); …Run Code Online (Sandbox Code Playgroud) 此代码类型检查并编译,然后崩溃。如何保存CGImage到,Data以便以后可以再次阅读。
let cgi: CGImage? = ...
var mData = Data()
let imageDest = CGImageDestinationCreateWithData(mData as! CFMutableData,
kUTTypePNG, 1, nil)!
CGImageDestinationAddImage(imageDest, cgi!, nil)
CGImageDestinationFinalize(imageDest)
Run Code Online (Sandbox Code Playgroud)
最后一行崩溃。控制台错误是:
2018-01-17 19:25:43.656664-0500 HelloPencil[2799:3101092] -[_NSZeroData
appendBytes:length:]: unrecognized selector sent to instance 0x1c80029c0
2018-01-17 19:25:43.658420-0500 HelloPencil[2799:3101092] *** Terminating app
due to uncaught exception 'NSInvalidArgumentException', reason:
'-[_NSZeroData appendBytes:length:]: unrecognized selector
sent to instance 0x1c80029c0'
Run Code Online (Sandbox Code Playgroud)
Xcode建议使用从Data到的转换CFMutableData,但这也许是错误的。
我想创建Photos类似的视频视图,在页脚中将有一秒的视频帧。
为此我正在使用这段代码
var imgs : [UIImage] = []
let assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: video)
assetImgGenerate.appliesPreferredTrackTransform = true
let duration = Int(CMTimeGetSeconds(video.duration))
for i in 0 ... duration {
if let img = generateFrames(assetImgGenerate : assetImgGenerate , fromTime: Float64(i))
{
imgs.append(img)
}
Run Code Online (Sandbox Code Playgroud)
该代码运行良好。我得到了与我想要的相同的结果。
现在的问题是 -如果视频大小超过 50 秒并且我正在提取 uiimage,那么当内存超出设备的可用空间时,我的应用程序会崩溃。
我的视频时长为 120 到 200 秒。在内存管理方面有什么更好的方法呢?(我无法延迟加载图像,因为我希望将图像预加载到屏幕中。)
编辑
func generateFrames(assetImgGenerate : AVAssetImageGenerator, fromTime:Float64) -> UIImage? {
let time : CMTime = CMTimeMakeWithSeconds(fromTime, 1)
var img: CGImage?
img = try? assetImgGenerate.copyCGImage(at:time, actualTime: …Run Code Online (Sandbox Code Playgroud) 问题:缩小图像的裁剪很好.使用放大的图像进行裁剪会将图像显示在应该是的上方.我在那里的yOffset是因为我想要的裁剪方块从scrollview所在的下方开始.
码:
CGRect rect;
float yOffset = 84;
rect.origin.x = floorf([scrollView contentOffset].x * zoomScale);
rect.origin.y = floorf(([scrollView contentOffset].y + yOffset) * zoomScale);
rect.size.width = floorf([scrollView bounds].size.width * zoomScale);
rect.size.height = floorf((320 * zoomScale));
if (rect.size.width > 320) {
rect.size.width = 320;
}
if (rect.size.height > 320) {
rect.size.height = 320;
}
CGImageRef cr = CGImageCreateWithImageInRect([[imageView image] CGImage], rect);
UIImage *img = imageView.image; //[UIImage imageWithCGImage:cr];
UIGraphicsBeginImageContext(rect.size);
// translated rectangle for drawing sub image
CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, 320.0f, 320.0f);
NSLog(@"drawRect: …Run Code Online (Sandbox Code Playgroud) cgimage ×12
uiimage ×7
swift ×4
ios ×3
cgimageref ×2
objective-c ×2
avasset ×1
bitmap ×1
cashapelayer ×1
cfdata ×1
cocoa ×1
foundation ×1
glkit ×1
ios8 ×1
iphone ×1
macos ×1
memory-leaks ×1
nsimage ×1
screenshot ×1
size ×1
swift4 ×1