mirror of
https://github.com/zhigang1992/PINRemoteImage.git
synced 2026-04-22 11:06:56 +08:00
Respect the maximum size of CIContexts
This commit is contained in:
@@ -24,8 +24,6 @@
|
||||
@property (nonatomic, strong) UIImage *cachedImage;
|
||||
@property (nonatomic, assign) NSUInteger currentThreshold;
|
||||
@property (nonatomic, assign) float bytesPerSecond;
|
||||
@property (nonatomic, strong) CIContext *processingContext;
|
||||
@property (nonatomic, strong) CIFilter *gaussianFilter;
|
||||
@property (nonatomic, assign) NSUInteger scannedByte;
|
||||
@property (nonatomic, assign) NSInteger sosCount;
|
||||
@property (nonatomic, strong) NSLock *lock;
|
||||
@@ -43,12 +41,22 @@
|
||||
@synthesize estimatedRemainingTimeThreshold = _estimatedRemainingTimeThreshold;
|
||||
@synthesize startTime = _startTime;
|
||||
|
||||
static CIContext *GPUProcessingContext = nil;
|
||||
static CIContext *CPUProcessingContext = nil;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
self.lock = [[NSLock alloc] init];
|
||||
self.lock.name = @"PINProgressiveImage";
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
//CIContexts are immutable and threadsafe
|
||||
CPUProcessingContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @YES}];
|
||||
GPUProcessingContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @NO, kCIContextPriorityRequestLow: @YES}];
|
||||
});
|
||||
|
||||
_imageSource = CGImageSourceCreateIncremental(NULL);;
|
||||
self.size = CGSizeZero;
|
||||
self.isProgressiveJPEG = NO;
|
||||
@@ -76,7 +84,6 @@
|
||||
- (void)dealloc
|
||||
{
|
||||
[self.lock lock];
|
||||
self.processingContext = nil;
|
||||
if (self.imageSource) {
|
||||
CFRelease(_imageSource);
|
||||
}
|
||||
@@ -92,7 +99,6 @@
|
||||
{
|
||||
[self.lock lock];
|
||||
self.inBackground = YES;
|
||||
self.processingContext = nil;
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
@@ -336,32 +342,36 @@
|
||||
//Must be called within lock
|
||||
- (UIImage *)postProcessImage:(UIImage *)inputImage withProgress:(float)progress
|
||||
{
|
||||
if (inputImage == nil) {
|
||||
if (inputImage.CGImage == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (self.processingContext == nil) {
|
||||
self.processingContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(self.inBackground), kCIContextPriorityRequestLow: @YES}];
|
||||
}
|
||||
|
||||
if (self.gaussianFilter == nil) {
|
||||
self.gaussianFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
|
||||
[self.gaussianFilter setDefaults];
|
||||
}
|
||||
CIFilter *gaussianFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
|
||||
[gaussianFilter setDefaults];
|
||||
|
||||
UIImage *outputUIImage = nil;
|
||||
if (self.processingContext && self.gaussianFilter) {
|
||||
[self.gaussianFilter setValue:[CIImage imageWithCGImage:inputImage.CGImage]
|
||||
|
||||
CIContext *processingContext = GPUProcessingContext;
|
||||
if (self.inBackground) {
|
||||
processingContext = CPUProcessingContext;
|
||||
}
|
||||
|
||||
if (processingContext.inputImageMaximumSize.height < inputImage.size.height || processingContext.inputImageMaximumSize.width < inputImage.size.width || processingContext.outputImageMaximumSize.height < inputImage.size.height || processingContext.outputImageMaximumSize.width < inputImage.size.width) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (processingContext && gaussianFilter) {
|
||||
[gaussianFilter setValue:[CIImage imageWithCGImage:inputImage.CGImage]
|
||||
forKey:kCIInputImageKey];
|
||||
|
||||
CGFloat radius = inputImage.size.width / 50.0;
|
||||
radius = radius * MAX(0, 1.0 - progress);
|
||||
[self.gaussianFilter setValue:[NSNumber numberWithFloat:radius]
|
||||
[gaussianFilter setValue:[NSNumber numberWithFloat:radius]
|
||||
forKey:kCIInputRadiusKey];
|
||||
|
||||
CIImage *outputImage = [self.gaussianFilter outputImage];
|
||||
CIImage *outputImage = [gaussianFilter outputImage];
|
||||
if (outputImage) {
|
||||
CGImageRef outputImageRef = [self.processingContext createCGImage:outputImage fromRect:CGRectMake(0, 0, inputImage.size.width, inputImage.size.height)];
|
||||
CGImageRef outputImageRef = [processingContext createCGImage:outputImage fromRect:CGRectMake(0, 0, inputImage.size.width, inputImage.size.height)];
|
||||
|
||||
if (outputImageRef) {
|
||||
//"decoding" the image here copies it to CPU memory?
|
||||
@@ -371,10 +381,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (outputUIImage == nil) {
|
||||
outputUIImage = inputImage;
|
||||
}
|
||||
|
||||
return outputUIImage;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user