ios需要理解图片原始数据metadata图片显示内存区别处理分辨率图片大小关系,

位图的大小计算公式

图片width x heigth x 4(ARGB)

对于大图下载需要理解,沙盒作用.

对于大图上传,不能一次性加载压缩等处理可以使用分片算法再进行上传

对于大图显示,可以采用gpu模式渲染显示。整体思维如下:

        先计算好原图片每个分片CGRect然后在根据设备获取到对应的缩放后的分片CGRect缩放的比例也是根据设备来设定。

        缩放后的分片CGRectp1生成缩放后的小分片,并且绘制屏幕,这样一直循环把原图片全部的每个分片全部生成对应缩放的小分片然后绘制。

        以上效果,最终加载出来的图片质量上虽然没有太大变化,但是图片分辨率(即大小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 &amp;&amp; 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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注