2009-09-02 16 views
0

私は自分のアプリにUITableViewを持っていて、幅は固定されていて高さが異なる画像を読み込む必要があります。私はNSOperationQueueを使用して画像の非同期をダウンロードし、サイズ変更とトリミングのために私はこのポストでJane Salesが提供するソリューションを使用しようとしましたlink textUITableViewCellsで表示する前に画像のサイズを変更してトリミングする

私はカスタムUITableViewCellクラスを作成しました。キューイングされた操作がイメージのダウンロードを完了したときに呼び出されるメソッドがあります。メソッドが正しく呼び出され、画像が表示されます。 Janeが提案した方法で画像のサイズを変更しようとすると、問題が発生します。 に到達したとき[sourceImage drawInRect:thumbnailRect];私はexecの不正なアクセスエラーを受け取り、私は理由を理解できません。

- (void) setupImage:(UIImage *) anImage{ 
    UIImage *resized = [anImage imageByScalingAndCroppingForSize:CGSizeMake(64, 59)]; 
    if(resized == nil) 
     resized = [UIImage newImageFromResource:@"thumb2.png"]; 
    [thumbnailView setImage:resized]; 
} 

setupImage NSOperationQueueがアニメージュのダウンロードアクションを完了したときに呼び出される関数です:私はこのようなメソッドが呼び出します。

誰かが、画像のサイズを変更して画像を切り抜こうとすると、悪いアクセスエラーが発生する理由を私に教えてもらえますか?私はテーブルビューの外で同じ機能を使用してみました。ケースの80%が動作しますが、同じexecの不正なアクセスエラーが発生する場合があります。

は ソリン

+0

私はシミュレータでアプリケーションをテストすると、execの不正なアクセスエラーがスローされないという事実は興味深いです。 iPhone 3Gでテストすると、サイズ変更や切り抜きを試みるときにエラーがスローされます。 –

+0

私はあなたのアプリのサンドボックスに画像を保存することをアドバイスしたいと思います。 – Daniel

+0

私はUITableViewCellでその場でイメージをトリミングするのはかなり高価だと思います。 – runmad

答えて

3

これは私が(コードがJane Sales solutionからである)

@implementation UIImage (Extras) 
#pragma mark - 
#pragma mark Scale and crop image 

- (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize 
{ 
UIImage *sourceImage = self; 
UIImage *newImage = nil;   
CGSize imageSize = sourceImage.size; 
CGFloat width = imageSize.width; 
CGFloat height = imageSize.height; 
CGFloat targetWidth = targetSize.width; 
CGFloat targetHeight = targetSize.height; 
CGFloat scaleFactor = 0.0; 
CGFloat scaledWidth = targetWidth; 
CGFloat scaledHeight = targetHeight; 
CGPoint thumbnailPoint = CGPointMake(0.0,0.0); 

if (CGSizeEqualToSize(imageSize, targetSize) == NO) 
     { 
     CGFloat widthFactor = targetWidth/width; 
     CGFloat heightFactor = targetHeight/height; 

     if (widthFactor > heightFactor) 
       scaleFactor = widthFactor; // scale to fit height 
     else 
       scaleFactor = heightFactor; // scale to fit width 
     scaledWidth = width * scaleFactor; 
     scaledHeight = height * scaleFactor; 

     // center the image 
     if (widthFactor > heightFactor) 
       { 
       thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
       } 
     else 
       if (widthFactor < heightFactor) 
         { 
         thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; 
         } 
     }  

UIGraphicsBeginImageContext(targetSize); // this will crop 

CGRect thumbnailRect = CGRectZero; 
thumbnailRect.origin = thumbnailPoint; 
thumbnailRect.size.width = scaledWidth; 
thumbnailRect.size.height = scaledHeight; 

[sourceImage drawInRect:thumbnailRect]; 

newImage = UIGraphicsGetImageFromCurrentImageContext(); 
if(newImage == nil) 
     NSLog(@"could not scale image"); 

//pop the context to get back to the default 
UIGraphicsEndImageContext(); 
return newImage; 
} 

UIImagesのサイズを変更してcropingのために使用していますものです前述のように上記の関数を呼び出します。

- (void) setupImage:(UIImage *) anImage 
{ 
    UIImage *resized = [anImage imageByScalingAndCroppingForSize:CGSizeMake(64, 59)]; 
    [thumbnailView setImage:resized]; 
} 

セルがテーブルビューに表示されると、画像は非同期にダウンロードされます。 setupImage関数は、NSOperationから非同期にダウンロードするイメージを受け取ります。上記のように問題は、[sourceImage drawInRect:thumbnailRect]に達したときです。

thumbnailViewは、私のカスタムTableViewCellのサブビューであるUIImageViewです。

これは私のコードで何を使用しているかについて少しはっきりしていることを願っています。 ありがとうございました。 Sorin

0

は、次のコードを試してみてください、事前にありがとうございます。 createImage:image:width:heightメソッドには、ソースCGImageRefと、返される最終的なUIImageの新しい幅と高さが必要です。ソースとしてUIImageを使用する場合は、次のように対応するCGImageRefを取得することができます。

UIImage *sourceImage; 
CGImageRef *sourceRef = [sourceImage CGImage]; 

     // Draw the image into a pixelsWide x pixelsHigh bitmap and use that bitmap to 
     // create a new UIImage 
     - (UIImage *) createImage: (CGImageRef) image width: (int) pixelWidth height: (int) pixelHeight 
     { 
      // Set the size of the output image 
      CGRect aRect = CGRectMake(0.0f, 0.0f, pixelWidth, pixelHeight); 
      // Create a bitmap context to store the new thumbnail 
      CGContextRef context = MyCreateBitmapContext(pixelWidth, pixelHeight); 
      // Clear the context and draw the image into the rectangle 
      CGContextClearRect(context, aRect); 
      CGContextDrawImage(context, aRect, image); 
      // Return a UIImage populated with the new resized image 
      CGImageRef myRef = CGBitmapContextCreateImage (context); 

      UIImage *img = [UIImage imageWithCGImage:myRef]; 

      free(CGBitmapContextGetData(context)); 
      CGContextRelease(context); 
      CGImageRelease(myRef); 

      return img; 
     } 



     // MyCreateBitmapContext: Source based on Apple Sample Code 
     CGContextRef MyCreateBitmapContext (int pixelsWide, 
              int pixelsHigh) 
     { 
      CGContextRef context = NULL; 
      CGColorSpaceRef colorSpace; 
      void *   bitmapData; 
      int    bitmapByteCount; 
      int    bitmapBytesPerRow; 

      bitmapBytesPerRow = (pixelsWide * 4); 
      bitmapByteCount  = (bitmapBytesPerRow * pixelsHigh); 

      colorSpace = CGColorSpaceCreateDeviceRGB(); 
      bitmapData = malloc(bitmapByteCount); 
      if (bitmapData == NULL) 
      { 
       fprintf (stderr, "Memory not allocated!"); 
       CGColorSpaceRelease(colorSpace); 
       return NULL; 
      } 
      context = CGBitmapContextCreate (bitmapData, 
              pixelsWide, 
              pixelsHigh, 
              8, 
              bitmapBytesPerRow, 
              colorSpace, 
              kCGImageAlphaPremultipliedLast); 
      if (context== NULL) 
      { 
       free (bitmapData); 
       CGColorSpaceRelease(colorSpace); 
       fprintf (stderr, "Context not created!"); 
       return NULL; 
      } 
      CGColorSpaceRelease(colorSpace); 

      return context; 
     } 
+0

私はそれを試して、それが動作するかどうかを確認します。ありがとう、私はフィードバックを返します。ソーリン –

+0

それはあなたのために働いたのですか? –

関連する問題