ios需要理解图片原始数据metadata,图片显示内存区别;处理分辨率与图片大小关系,
图片width x heigth x 4(ARGB)
对于大图上传,不能一次性加载压缩等处理,可以使用分片算法再进行上传。
对于大图显示,可以采用gpu的模式性渲染显示。整体思维如下:
先计算好原图片的每个分片CGRect,然后在根据设备获取到对应的缩放后的分片CGRect,缩放的比例也是根据设备来设定。
缩放后的分片CGRect和 p1生成缩放后的小分片,并且绘制到屏幕,这样一直循环把原图片全部的每个小分片全部生成对应缩放的小分片,然后绘制。
以上效果,最终加载出来的图片质量上虽然没有太大变化,但是图片分辨率(即大小width x heigth)变小了。所以如果大图片的显示可以这么处理。
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
sourceImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kImageFilename ofType:nil]];
if( sourceImage == nil ) NSLog(@”input image not found!”);
sourceResolution.width = CGImageGetWidth(sourceImage.CGImage);
sourceResolution.height = CGImageGetHeight(sourceImage.CGImage);
sourceTotalPixels = sourceResolution.width * sourceResolution.height;
sourceTotalMB = sourceTotalPixels / pixelsPerMB;
imageScale = destTotalPixels / sourceTotalPixels;
destResolution.width = (int)( sourceResolution.width * imageScale );
destResolution.height = (int)( sourceResolution.height * imageScale );
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
int bytesPerRow = bytesPerPixel * destResolution.width;
void* destBitmapData = malloc( bytesPerRow * destResolution.height );
if( destBitmapData == NULL ) NSLog(@”failed to allocate space for the output image!”);
destContext = CGBitmapContextCreate( destBitmapData, destResolution.width, destResolution.height, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast );
if( destContext == NULL ) {
free( destBitmapData );
NSLog(@”failed to create the output bitmap context!”);
}
CGColorSpaceRelease( colorSpace );
CGContextTranslateCTM( destContext, 0.0f, destResolution.height );
CGContextScaleCTM( destContext, 1.0f, -1.0f );
sourceTile.size.width = sourceResolution.width;
sourceTile.size.height = (int)( tileTotalPixels / sourceTile.size.width );
NSLog(@”source tile size: %f x %f”,sourceTile.size.width, sourceTile.size.height);
sourceTile.origin.x = 0.0f;
destTile.size.width = destResolution.width;
destTile.size.height = sourceTile.size.height * imageScale;
destTile.origin.x = 0.0f;
NSLog(@”dest tile size: %f x %f”,destTile.size.width, destTile.size.height);
sourceSeemOverlap = (int)( ( destSeemOverlap / destResolution.height ) * sourceResolution.height );
NSLog(@”dest seem overlap: %f, source seem overlap: %f”,destSeemOverlap, sourceSeemOverlap);
CGImageRef sourceTileImageRef;
int iterations = (int)( sourceResolution.height / sourceTile.size.height );
int remainder = (int)sourceResolution.height % (int)sourceTile.size.height;
if( remainder ) iterations++;
float sourceTileHeightMinusOverlap = sourceTile.size.height;
sourceTile.size.height += sourceSeemOverlap;
destTile.size.height += destSeemOverlap;
NSLog(@”beginning downsize. iterations: %d, tile height: %f, remainder height: %d”, iterations, sourceTile.size.height,remainder );
for( int y = 0; y < iterations; ++y ) {
NSAutoreleasePool* pool2 = [[NSAutoreleasePool alloc] init];
NSLog(@”iteration %d of %d”,y+1,iterations);
sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap;
destTile.origin.y = ( destResolution.height ) – ( ( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + destSeemOverlap );
sourceTileImageRef = CGImageCreateWithImageInRect( sourceImage.CGImage, sourceTile );
if( y == iterations – 1 && remainder ) {
float dify = destTile.size.height;
destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale;
dify -= destTile.size.height;
destTile.origin.y += dify;
}
CGContextDrawImage( destContext, destTile, sourceTileImageRef );
CGImageRelease( sourceTileImageRef );
[sourceImage release];
// free all objects that were sent –autorelease within the scope of this loop.
[pool2 drain];
if( y < iterations – 1 ) {
sourceImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kImageFilename ofType:nil]];
[self performSelectorOnMainThread:@selector(updateScrollView:) withObject:nil waitUntilDone:YES];
}
}
NSLog(@”downsize complete.”);
[self performSelectorOnMainThread:@selector(initializeScrollView:) withObject:nil waitUntilDone:YES];
CGContextRelease( destContext );
[pool drain];
}
-(void)createImageFromContext {
CGImageRef destImageRef = CGBitmapContextCreateImage( destContext );
if( destImageRef == NULL ) NSLog(@”destImageRef is null.”);
self.destImage = [UIImage imageWithCGImage:destImageRef scale:1.0f orientation:UIImageOrientationDownMirrored];
CGImageRelease( destImageRef );
if( destImage == nil ) NSLog(@”destImage is nil.”);
}
-(void)readDataWithChunk:(NSInteger)chunk file:(CNFile*)file{
总片数的获取方法:
int offset =1024*1024;(每一片的大小是1M)
NSInteger chunks = (file.fileSize%1024==0)?((int)(file.fileSize/1024*1024)):((int)(file.fileSize/(1024*1024) + 1));
NSLog(@"chunks = %ld",(long)chunks);
将文件分片,读取每一片的数据:
NSData* data;
NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:file.filePath];
[readHandle seekToFileOffset:offset * chunk];
data = [readHandle readDataOfLength:offset];
}
原文地址:https://blog.csdn.net/zmfsl110/article/details/122945176
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_10173.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!