我正在尝试通过自定义裁剪器裁剪图像.不是来自UIImagePickerController的.现在我通过处理UIImagePicker的委托来显示从UIImgeView中的图像选择器捕获的图像:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
imvOriginalImage.image = image;
}
Run Code Online (Sandbox Code Playgroud)
对于裁剪,我必须将此Image转换为CGImageRef.以纵向模式捕获图像.现在,当我在CGImageRef中转换此图像时,图像方向会发生变化.即使我使用以下内容:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
//imvOriginalImage.image = image;
CGImageRef imgRef = [image CGImage];
UIImage *img = [UIImage imageWithCGImage:imgRef];
[imvOriginalImage setImage:img];
Run Code Online (Sandbox Code Playgroud)
}
图像方向发生变化.这仅适用于以纵向模式拍摄的图像.风景图像没有这个问题.
提前致谢.
我在从 CIImage 获取 UIImage 时遇到问题。下面的代码行在 iOS6 上工作正常:(输出图像是 CIImage)
self.imageView = [UIImage imageWithCIImage:outputImage];
Run Code Online (Sandbox Code Playgroud)
或者
[self.imageView setImage:[UIImage imageWithCIImage:outputImage]];
Run Code Online (Sandbox Code Playgroud)
当我在运行 iOS 5 的设备上运行同一行代码时,imageView 为空白。如果我记录 UIImage 的 size 属性,它是正确的,但图像永远不会显示在屏幕上。
当我使用 CGImageRef(如下所示)时,它在两个设备上都可以正常工作,但是当我进行堆快照分析时,它会导致巨大的内存增长。
context = [CIContext contextWithOptions:nil];
CGImageRef ref = [context createCGImage:outputImage fromRect:outputImage.extent];
self.imageView.image = [UIImage imageWithCGImage:ref scale:1.0 orientation:UIImageOrientationUp];
CGImageRelease(ref);
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么 UIImage imageWithCIImage 不起作用?根据 UIImage 类参考,它应该适用于 iOS5 及更高版本。另外为什么使用 CGImageRef 会导致如此大量的堆增长?
谢谢
我正在尝试从屏幕缓冲区中读取像素,我正在创建一个CGImageRef
with CGDisplayCreateImage
,但是值的值CGImageGetWidth
和CGImageGetBytesPerRow
"没有意义"在一起,将每行的字节数除以每个像素的字节数给出了每行1376个像素,但是图像的宽度是1366.
这里发生了什么?图像中是否有某种填充?如何安全地读取数据,并获得正确的结果?
编辑:重现此操作所需的最小代码如下:
#import <Foundation/Foundation.h>
#import <ApplicationServices/ApplicationServices.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
CGImageRef image = CGDisplayCreateImage(CGMainDisplayID());
size_t width = CGImageGetWidth(image);
size_t bpr = CGImageGetBytesPerRow(image);
size_t bpp = CGImageGetBitsPerPixel(image);
size_t bpc = CGImageGetBitsPerComponent(image);
size_t bytes_per_pixel = bpp / bpc;
NSLog(@"%li %li", bpr/bytes_per_pixel, width);
CGImageRelease(image);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) 假设你从一个UIImage开始,你想要裁剪它.最常见的方法是使用CGImageCreateWithImageInRect来获取CGImageRef并从中创建一个新图像,如下所示:
CGRect cropRect = CGRectMake(x*width, y*height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
Run Code Online (Sandbox Code Playgroud)
现在让我们说你以后需要将这个UIImage转换为NSData对象.例如,如果您希望使用NSKeyedArchiver将映像存储在磁盘上,则会发生这种情况.或者,您可以通过以下显式执行以下操作来获取NSData对象:
NSData *imageData = UIImagePNGRepresentation(croppedImage);
Run Code Online (Sandbox Code Playgroud)
我做了这个,后来我尝试通过以下方式重建一个新的UIImage对象:
UIImage *image = [UIImage imageWithData:imageData];
Run Code Online (Sandbox Code Playgroud)
我为一系列48张图片做了这个.他们中的大多数都很好,但是在每4张图片之后,接下来的两张图片都被破坏了,每张图片的顶部和底部都被交换了.如果我将转换转换为NSData并再次返回,它可以正常工作.如果我使用NSKeyedArchiver将图像数组写入磁盘(我猜它在其编码例程中调用类似UIImagePNGRepresentation的东西),我也会得到完全相同的问题.我的理论是这必须与我如何从CGImageRefs构建图像有关.
这是什么解决方法?我似乎无法弄清楚如何将CGImageRefs放入NSData对象,我更喜欢一个正确构建UIImage的解决方案,以便它可以被序列化.
编辑:
有些人要求运行实际的代码,所以我在这里添加它
UIImage *image = self.animationObject.image;
for (int y=0; y<[self.animationInfoObject.numInY intValue]; y++) {
for (int x=0; x<[self.animationInfoObject.numInX intValue]; x++) {
CGRect cropRect = CGRectMake(x*width, y*height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
NSData *imageData = UIImageJPEGRepresentation(croppedImage, 1.0);
[self addImageToArray:imageData];
CFRelease(imageRef);
}
} …
Run Code Online (Sandbox Code Playgroud) 我试图调整一个10x10像素的CGImageRef,像这样捕获:
CGImageRef imageRef = CGImageCreateWithImageInRect(screenShot, CGRectMake(mouseLoc.x-5, screen_height-mouseLoc.y-5, 10, 10));
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, maskImage.size.height*4, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(mainViewContentContext, NSMakeRect(0,0, maskImage.size.width, maskImage.size.height), imageRef);
Run Code Online (Sandbox Code Playgroud)
我当前的方法是:
CGDataProviderRef provider = CGImageGetDataProvider(imageRef);
imageData.rawData = CGDataProviderCopyData(provider);
imageData.imageData = (UInt8 *) CFDataGetBytePtr(imageData.rawData);
Run Code Online (Sandbox Code Playgroud)
我每秒只能得到约30帧。我知道性能下降的一部分是复制数据,如果我可以访问字节流而不让它自动为我创建副本,那将是很好的。
我试图让它尽可能快地处理CGImageRefs,有没有更快的方法?
这是我的工作解决方案片段:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
//timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 //2000.0
// target:self
// selector:@selector(timerLogic)
// userInfo:nil
// repeats:YES];
leagueGameState = [LeagueGameState new];
[self updateWindowList];
lastTime = CACurrentMediaTime();
// Create a capture session
mSession = [[AVCaptureSession alloc] init];
// Set the session preset as you wish
mSession.sessionPreset = AVCaptureSessionPresetMedium;
// If you're on a multi-display system and you …
Run Code Online (Sandbox Code Playgroud) 我得到了以下访问PHAsset的代码.我需要传递一个CGImage:
let imageManager = PHImageManager.defaultManager()
imageManager.requestImageDataForAsset(self.asset!, options: nil, resultHandler:{
(data, responseString, imageOriet, info) -> Void in
let imageData: NSData = data!
if let imageSource = CGImageSourceCreateWithData(imageData, nil) {
let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
//How do I create a CGImage now?
}
})
Run Code Online (Sandbox Code Playgroud)
我需要提取一个CGImage.遇到麻烦......
我用相机制作了相机AVFoundation
.
一旦我AVCaptureStillImageOutput
完成了它的captureStillImageAsynchronouslyFromConnection:completionHandler:
方法,我就像这样创建一个NSData对象:
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
Run Code Online (Sandbox Code Playgroud)
一旦我有了这个NSData
对象,我想将图像 - 不用 - 转换为a UIImage
.我发现我可以转换成a CGImage
来这样做.
在我拥有imageData之后,我开始转换为CGImage的过程,但我发现CGImageRef
最终比NSData
对象大三十倍.
下面是我用来转换为代码CGImage
来自NSData
:
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)(imageData));
CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
Run Code Online (Sandbox Code Playgroud)
如果我尝试NSLog
超出图像的大小,当它NSData
是一个1.5-2兆字节的图像时,它会达到30兆字节!
size_t imageSize = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef);
NSLog(@"cgimage size = %zu",imageSize);
Run Code Online (Sandbox Code Playgroud)
我想也许当你从NSData转到CGImage时,图像会解压缩,然后如果我转换回NSData,它可能会回到正确的文件大小.
imageData = (NSData *) CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef)));
Run Code Online (Sandbox Code Playgroud)
以上与对象NSData
相同.length
CGImageRef
如果我尝试保存图像,则图像是无法打开的30mb图像.
我对使用CGImage完全不熟悉,所以我不确定我是从NSData转换为CGImage还是错误地返回,或者我是否需要调用某种方法再次解压缩.
提前致谢,
将
我很想在我的项目中加入arc.我正在尝试理解__bridge及其小朋友,以便在从容器中添加和删除它时可以正确地投射我的CGImageRef.
我在我的一条线上得到了"存储对象的潜在泄漏......".这是我的代码的基本循环:
CGImageRef renderedRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
[_array addObject: (__bridge_transfer id)renderedRef];//_array is an iVar
Run Code Online (Sandbox Code Playgroud)
然后在某个地方,我这样做:
CGImageRef iRef = (__bridge_retained CGImageRef)array[0];
//then I do something fancy with iRef
//at the end of the method, I get "Potential leak of an object stored…"
//I have no idea what to do
//I've tried CGImageRelease(iRef); but it still doesn't change the warning.
Run Code Online (Sandbox Code Playgroud)
有人可以对此有所了解吗?另外,我尝试过只使用__bridge,但这没有什么区别.
编辑1:
我扩展了分析仪结果并跟踪发生的情况.这是因为我在这样的方法中使用iRef:[self doSomethingFancy:iRef]; 在那种方法中,iRef被保留但未被释放.所以这修复了警告,但我仍然有点困惑.
关于何时使用各种__bridge演员,我不是很清楚.在ARC下,以下是否增加了引用计数?
CGImageRef iRef = (__bridge CGImageRef)array[0];
Run Code Online (Sandbox Code Playgroud)
此外,在某些时候,如果我告诉我的_array iVar删除AllObjects,那会减少他们的引用计数吗?
objective-c ios cgimageref automatic-ref-counting toll-free-bridging
以下是如何在上下文中绘制UIImage:
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
[someUIImage drawInRect:CGRectMake(...)];
[someOtherUIImage drawInRect:CGRectMake(...)];
[someOtherUIImage drawInRect:CGRectMake(...)];
UIImage *yourResult = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)
没问题.但是,假设我有一个以某种方式构建的CGImageRef.
CGImageRef happyImageRef = CGImageCreateWithImageInRect(blah blah);
Run Code Online (Sandbox Code Playgroud)
我想把它绘制到上下文中.
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
[ happyImageRef .. somehowDrawInRect:CGRectMake(...)];
UIImage *yourResult = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)
你是怎样做的?
要清楚,显然你可以将它转换为UIImage
UIImage *wasteful = [UIImage imageWithCGImage:happyImageRef];
Run Code Online (Sandbox Code Playgroud)
但这看起来非常低效.怎么做?
我确定我很困惑或遗漏了一些简单的东西,谢谢.
cgimageref ×10
objective-c ×5
cgimage ×3
ios ×3
uiimage ×3
iphone ×2
nsdata ×2
xcode ×2
ciimage ×1
cocoa ×1
core-image ×1
drawinrect ×1
framebuffer ×1
macos ×1
nsimage ×1
scaling ×1
swift ×1