2012年7月5日木曜日

animatedGIF with ImageIO

ImageIOを使ったアニメーションGIF(というかアニメーションUIImage)は意外にあっさり動いた。ただUIGraphicsBeginImageContext〜でmixしたら当然ながらアニメは止まっちゃう。とりあえずUIImageViewのサブクラス修正版はこんな感じ。

- (void)makeImage:(NSMutableData *)rdata{
 if(multiFlg){
  UIImage *img=[UIImage imageWithData:rdata];
  [imgArr addObject:img];
  [imgArr addObject:nwf(img.size.width)];[imgArr addObject:nwf(img.size.height)];[imgArr addObject:nwf(img.size.width/img.size.height)];
  if([imgArr count]/4<[photourl count]){
   imgnum++;[self loadPhoto];
  }
  else{ //tiling routine
   int curx=0,cury=0,k=0;
   for(int j=0;j<[imgArr count]/4;j++){
    if([[imgArr objectAtIndex:j*4+3]floatValue]<sr&&[imgArr count]/4>j+1){
     int over3=2;
     CGFloat firstw=ofv(imgArr, j*4+1),firsth=ofv(imgArr, j*4+2),firstr=firsth/firstw;
     CGFloat nextw=ofv(imgArr, (j+1)*4+1),nexth=ofv(imgArr, (j+1)*4+2);
     CGFloat newh=firstr*((sw*nexth)/(nextw*firstr+nexth));
     while (sw/newhj+over3) {
      nextw=ofv(imgArr, (j+over3)*4+1),nexth=ofv(imgArr, (j+over3)*4+2);
      newh=(newh/sw)*((sw*nexth)/(nextw*(newh/sw)+nexth));
      over3++;
     }
     j+=1+(over3-2);
     UIGraphicsBeginImageContext(CGSizeMake(sw,cury+newh));
     if(mixedimg){[mixedimg drawAtPoint:CGPointMake(0, 0)];}
     while(k<j+1){
      CGFloat neww=newh*[[imgArr objectAtIndex:k*4]size].width/[[imgArr objectAtIndex:k*4]size].height;
      [[imgArr objectAtIndex:k*4]drawInRect:(CGRectMake(curx,cury,neww,newh))];
      curx+=neww;k++;
     }
     cury+=newh;curx=0;
     mixedimg=UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
    }else{
     UIGraphicsBeginImageContext(CGSizeMake(sw,cury+sw*[[imgArr objectAtIndex:j*4]size].height/[[imgArr objectAtIndex:j*4]size].width));
     if(mixedimg) [mixedimg drawAtPoint:CGPointMake(0, 0)];
     CGFloat newh=sw*[[imgArr objectAtIndex:j*4]size].height/[[imgArr objectAtIndex:j*4]size].width;
     [[imgArr objectAtIndex:j*4]drawInRect:(CGRectMake(0,cury,sw,newh))];
     mixedimg=UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
     cury+=sw*[[imgArr objectAtIndex:j*4]size].height/[[imgArr objectAtIndex:j*4]size].width;
    }
   }
   [ai removeFromSuperview];
   self.image=mixedimg;
   [self abort];   
  }
 }
 else{
  [ai removeFromSuperview];
  if([[photourl objectAtIndex:0]hasSuffix:@"gif"]){
   CGImageSourceRef src=CGImageSourceCreateWithData((__bridge CFDataRef)rdata,NULL);
   NSDictionary *prop=[(__bridge NSDictionary*)CGImageSourceCopyProperties(src,NULL) objectForKey:(NSString*)kCGImagePropertyGIFDictionary];
   size_t count=CGImageSourceGetCount(src);
   NSMutableArray *GIFimages=[NSMutableArray array];   
   for(size_t i=0; i<count; i++){
    CGImageRef image=CGImageSourceCreateImageAtIndex(src,i,NULL);
    [GIFimages addObject:[UIImage imageWithCGImage:image]];
    CGImageRelease(image);
   }
   NSTimeInterval delay=[[prop objectForKey:(NSString*)kCGImagePropertyGIFDelayTime] doubleValue];
   if (!delay) delay=1.2;
   CFRelease(src);
   self.image=[UIImage animatedImageWithImages:GIFimages duration:delay];
  }else self.image=[UIImage imageWithData:data];
  [self abort];
 }
}

できた。
これでgif以外なら何枚でもタイリングしてself.imageにセットし、gifでも1枚ならImageIO使ってアニメーションするUIImageをself.imageにセットされる。gifを含んだ複数画像のpostはこいつ経由で1枚1枚親UIViewControllerにaddSubViewしていけばいけるんじゃないかな。本当かな。

0 件のコメント:

コメントを投稿