iOS 에서 큰 크기 의 그림 의 회전 과 크기 조정 인 스 턴 스 상세 설명
아이 폰 의 하드웨어 성능 제한 으로 아이 폰 6s 가 시 작 될 때 까지 최대 메모 리 를 2G 로 확장 했다.
그렇다 고 해서 응용 프로그램 이 사용 할 수 있 는 공간 이 2G 인 것 은 아니다.
10000 x 10000 의 그림 이 UIImageJPEG Representation 방법 으로 그림 을 메모리 데이터 로 변환 하면 피크 값 변동 이 있 습 니 다.
이곳 의 피크 수 치 는 사실 그림 이 압축 을 풀 때 발생 하 는 비트 맵 데이터 가 공간 을 차지 한 후에 야 우리 가 조작 할 수 있 는 NSData 로 바 뀌 었 다.
그 계산 공식 은 W x H x 4/1024/1024 즉 10000 x 10000 x4/1024/1024=381.4(M)이다.
이곳 은 381 M 의 소모 가 발생 하여 제때에 회수 되 지만 생각해 보면 그림 의 크기 가 크 고 수량 이 많 을 때 이상 이 발생 하기 쉽다.
본 고 는 iOS 의 큰 사이즈 그림 회전 과 크기 조정 에 관 한 내용 을 상세 하 게 소개 하고 참고 학습 을 제공 하 며 더 이상 말 하지 않 겠 습 니 다.다음은 구체 적 인 조작 을 말씀 드 리 겠 습 니 다.
빙빙 돌다
UIImage 대상 을 회전 시 키 면 프로젝트 를 할 때 반드시 UIImage 와 같은 방식 이 있 을 것 이 라 고 믿 습 니 다.
CGContextDrawImage 를 통 해 그림 그리 기
+ (UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation {
long double rotate = 0.0;
CGRect rect;
float translateX = 0;
float translateY = 0;
float scaleX = 1.0;
float scaleY = 1.0;
switch (orientation) {
case UIImageOrientationLeft:
rotate = M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = 0;
translateY = -rect.size.width;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
default:
rotate = 0.0;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = 0;
translateY = 0;
break;
}
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// CTM
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextRotateCTM(context, rotate);
CGContextTranslateCTM(context, translateX, translateY);
CGContextScaleCTM(context, scaleX, scaleY);
//
CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
return newPic;
}
여기에 새로운 그림 크기 공간 을 만 들 고 다시 그 리 는 것 이 문제 입 니 다.그림 의 크기 가 너무 클 때 메모리 사용량 이 너무 높 은 경우 가 발생 할 수 있 습 니 다.다음은 그림 에 필 터 를 추가 하 는 방법 을 소개 한다.
작업 대상 이 그림 인 이상 각종 필터 가 전시 된다.시스템 은 우리 에 게 몇 백 여 종의 필 터 를 제 공 했 는 지,이곳 의 필 터 는 단지 색깔 등 상태 에 변화 가 발생 하지 않 는 다.
그 중 에 우리 가 필요 로 하 는 필터 키 input Transform 이 있 습 니 다.
+ (UIImage *)getRotationImage:(UIImage *)image rotation:(CGFloat)rotation {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform" keysAndValues:kCIInputImageKey, ciImage, nil];
[filter setDefaults];
CGAffineTransform transform = CATransform3DGetAffineTransform([self rotateTransform:CATransform3DIdentity clockwise:NO angle:rotation]);
[filter setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:@"inputTransform"];
//
CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(NO)}];
CIImage *outputImage = [filter outputImage];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *result = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return result;
}
+ (CATransform3D)rotateTransform:(CATransform3D)initialTransform clockwise:(BOOL)clockwise angle:(CGFloat)angle {
CGFloat arg = angle*M_PI / 180.0f;
if(!clockwise){
arg *= -1;
}
//
CATransform3D transform = initialTransform;
transform = CATransform3DRotate(transform, arg, 0, 0, 1);
CGFloat _flipState1 = 0;
CGFloat _flipState2 = 0;
transform = CATransform3DRotate(transform, _flipState1*M_PI, 0, 1, 0);
transform = CATransform3DRotate(transform, _flipState2*M_PI, 1, 0, 0);
return transform;
}
이런 조작 을 통 해 GPU 를 이용 하여 이미지 조작 을 할 수 있어 소 모 를 어느 정도 줄 이 고 자원 을 절약 할 수 있다.크기 조정
그림 이 매우 큰 이상 우 리 는 크기 를 조정 하 는 방식 으로 그림 의 사 이 즈 를 줄 이 고 메모리 소 모 를 줄 이 며 이상 위험 을 낮 출 수 있다.
저 희 는 보통 UIImage 가 제공 하 는 시스템 방법 인 drawingRect 와 그 일련의 방법 으로 그림 크기 를 조정 합 니 다.
그러나 이런 조작의 결함 은 처음에 소 개 된 회전 과 마찬가지 로 실질 적 으로 그림 을 다시 그 리 는 것 이다.
그림 그리 기 를 통 해 그림 크기 조정 하기
+ (UIImage *)image:(UIImage *)image transformtoSize:(CGSize)Newsize {
// bitmap context
UIGraphicsBeginImageContext(Newsize);
//
[image drawInRect:CGRectMake(0, 0, Newsize.width, Newsize.height)];
// context
UIImage *TransformedImg=UIGraphicsGetImageFromCurrentImageContext();
// context
UIGraphicsEndImageContext();
//
return TransformedImg;
}
여 기 는 메모리 소모 입 니 다.그림 을 보면 큰 그림 에 대해 크기 를 조정 할 때 메모리 소모 피크 수 치 는 426 M 에 달 하고 시간 은 1.5s 정도 인 것 을 알 수 있다.우리 가 사용 하 는 휴대 전 화 는 아이 폰 X 이기 때문에 더 낮은 장치 에서 이것 이 얼마나 큰 손실 인지 이상 이 발생 하기 쉽다.
위의 방법 이 매우 큰 손실 을 입 었 으 니,우 리 는 다른 방식 을 보 자.
메모리 소모 부터 볼 게 요.
그림 을 통 해 알 수 있 듯 이 그림 크기 를 조정 할 때 메모리 가 소폭 증가 하고 발생 하 는 소 모 는 18M 이 며 소모 시간 도 1.5s 정도 이다.
이런 효 과 는 매우 현저 하 다.다음은 코드 를 보 겠 습 니 다.
+(UIImage *)resizeImage:(UIImage *)image toSize:(CGSize)size {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
// input image
CIFilter *filter = [CIFilter filterWithName:@"CIAffineTransform" keysAndValues:kCIInputImageKey, ciImage, nil];
//
[filter setDefaults];
//
CGFloat scale = 1;
if (size.width != CGFLOAT_MAX) {
scale = (CGFloat) size.width / image.size.width;
} else if (size.height != CGFLOAT_MAX) {
scale = (CGFloat) size.height / image.size.height;
}
//
CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale);
[filter setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:@"inputTransform"];
// GPU
CIContext *context = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(NO)}];
//
CIImage *outputImage = [filter outputImage];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:[outputImage extent]];
// UIImage ,
UIImage *result = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return result;
}
우리 가 이곳 에서 사용 하 는 것 과 회전 이 같은 방식 이라는 것 을 알 수 있다.그림 에 필 터 를 추가 하면 우리 의 수 요 를 안전하게 실현 할 수 있다.총결산
1.대형 사진 조작 에 대해 이런 사고방식 을 사용 할 수 있다.선생님 은 사이즈 가 작은 미리 보기 그림 을 만 든 다음 에 각종 조작 을 하면 자원 소 모 를 줄 일 수 있다.
2.코어 이미지.framework 를 통 해 이미지 처 리 를 한다.
3.코어 이미지.framework 에 대한 이 해 는 그림 과 동 영상 에 보 이 는 필 터 를 추가 할 수 있 을 뿐 이 필터 도 크기 조정 과 회전 을 지원 할 줄 은 몰 랐 다.
? 왜 CoreImage.framework 의 방식 이 안전 합 니까?
이 프레임 워 크 는 iOS 5 부터 사용 에 들 어가 CoreGraphics.framework,CoreVideo.framework,Image I/O.framework 를 통 해 데이터 처 리 를 하고,
CPU 와 GPU 사이 에서 연산 방식 을 자 유 롭 게 전환 할 수 있 습 니 다.
GPU 를 최대한 이용 하여 계산 하여 메모리 소 모 를 줄 일 수 있 습 니 다.
영상 을 실시 간 으로 필터 처리 할 수도 있다.
네 이 티 브 를 통 해 UIView 를 transform 작업 할 수 없 을 때 CoreImage.framework 는 친구 가 될 것 입 니 다.
가장 직접적인
Core Image is an image processing and analysis technology designed to provide near real-time processing for still and video images. It operates on image data types from the Core Graphics, Core Video, and Image I/O frameworks, using either a GPU or CPU rendering path. Core Image hides the details of low-level graphics processing by providing an easy-to-use application programming interface (API). You don't need to know the details of OpenGL, OpenGL ES, or Metal to leverage the power of the GPU, nor do you need to know anything about Grand Central Dispatch (GCD) to get the benefit of multicore processing. Core Image handles the details for you.
그것 은 이미 너 를 도와 모든 물건 을 다 처 리 했 으 니 대담 하 게 써 라.
문서. ( 코드 주소 )
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Swift의 패스트 패스Objective-C를 대체하기 위해 만들어졌지만 Xcode는 Objective-C 런타임 라이브러리를 사용하기 때문에 Swift와 함께 C, C++ 및 Objective-C를 컴파일할 수 있습니다. Xcode는 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.