2015-04-04 18 views
5

Bir UIImage ile başladığınızı ve bunu kırpmak istediğinizi varsayalım. Şimdi Sonradan bir NSData nesnesine bu UIImage dönüştürmek gerekir diyelimBir CGImageRef öğesinden oluşturulmuş bir UIImage nesnesini ham verilere dönüştürme ve geri dönme

CGRect cropRect = CGRectMake(x*width, y*height, width, height); 
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect); 
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef]; 

: En yaygın yöntem, bir CGImageRef almak için CGImageCreateWithImageInRect kullanabilir ve böylece ondan yeni bir resim oluşturmaktır. Örneğin, görüntüyü NSKeyedArchiver kullanarak diskte saklamak isterseniz bu gerçekleşir. Ya açıkça şu bir NSData yaparak dışarı nesne alabilirsiniz: Ben için yaptım

UIImage *image = [UIImage imageWithData:imageData]; 

:

NSData *imageData = UIImagePNGRepresentation(croppedImage); 

ben yaparak yeni bir UIImage nesnesini yeniden çalıştı daha sonra bu yaptı ve 48 görüntü dizisi. Birçoğu iyiydi, ama her 4 görüntüden sonra, sonraki 2, her bir resmin üst ve alt kısmı ile değiştirildi. Dönüştürmeyi NSData'ya geri alıp tekrar geri alırsam, iyi çalışıyor. Ben de diske görüntülerin bir dizi yazmak için NSKeyedArchiver kullanıyorsanız (aynı zamanda kendi kodlama rutin UIImagePNGRepresentation gibi bir şey çağrıları tahmin) kullanırsanız ben de aynı sorunu olsun. Benim teorim, CGImageRefs'den görüntüleri nasıl oluşturduğumla ilgili bir şey olmalı.

Bunun için geçici çözüm nedir? CGImageRefs'i NSData nesnesine nasıl yerleştireceğimi anlayamıyorum ve UIImage'ı seri hale getirecek şekilde doğru bir şekilde oluşturmayı tercih ederim.

Düzenleme:

Bazı insanlar yürütülüyor fiili kodu istenecektir, bu yüzden self.animationObject.image gelen görüntü numInX ve görüntülerin bir ızgara burada

UIImage *image = self.animationObject.image; 
for (int y=0; y<[self.animationInfoObject.numInY intValue]; y++) { 
    for (int x=0; x<[self.animationInfoObject.numInX intValue]; x++) { 
     CGRect cropRect = CGRectMake(x*width, y*height, width, height); 
     CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect); 
     UIImage *croppedImage = [UIImage imageWithCGImage:imageRef]; 
     NSData *imageData = UIImageJPEGRepresentation(croppedImage, 1.0); 
     [self addImageToArray:imageData]; 
     CFRelease(imageRef); 
    } 
} 

bunu ekliyorum ve her yöne DOĞRU görüntüler. Her bir görüntüyü 2B ızgaradan kırpıp kaydediyorum.

Daha sonra, görüntüleri canlandırmak için görüntüleri bir resim görünümünde koyuyorum.

 NSMutableArray *animationArray = [[NSMutableArray alloc] init]; 
    for (int frame=0; frame<[[photoObject frameArray] count]; frame++) { 
     NSData *imageData =[[photoObject imageArray] objectAtIndex:[[[photoObject frameArray] objectAtIndex:frame] integerValue]-1]; 
     UIImage *image = [UIImage imageWithData:imageData]; 
     [animationArray addObject:image]; 
    } 

Bunların hepsi bir iPhone 6 üzerinde çalışıyor ancak aynı zamanda görüntülerin ızgara uzun olduğunda sadece bir sorun gibi görünüyor bir iPhone 5. çalışmıyor: İşte kodudur. Örneğin, kullanıyorum örnek için self.animationObject.image 3 olarak numInY ve numInX 2 ve görüntünün toplam boyutu 1536x3072 (her mini görüntü 768x1024). Üstleri ve dipleri ters çevrilmiş en alttaki iki resim.

+0

Biraz daha yararlı ayrıntıları awolf için kredi. Her biri 2x3 ızgarada 6 küçük resim içeren kompozit görüntülerim var. Her görüntünün boyutu 768x1024'tür, bu nedenle bileşik görüntünün toplam boyutu 1536x3072'dir. Her bir kompozitin alt ve üst yarısı değiştirilmiş olan 5. ve 6. resimlerdir. Yani, CGImage hakkında, büyük bir görüntünün alt kısmına kırpmadan kaynaklanan bir şey olabilir, belki? Yine, UIImage'ın NSData'ya dönüştürülmediği ve tekrar geri dönmediği takdirde bunun mükemmel şekilde çalıştığından bahsetmeliyim. – Mike

+0

Yukarıdaki bu incelemede, genişlik 768, yükseklik 1024 ve x, 0 veya 1 ve y olduğunda 2 bozuluyor. Y, 0 veya 1 olduğunda iyi çalışıyor. Bu CGImageCreateWithImageInRect, yalnızca ile başa çıkamıyor büyük görüntüler mi? – Mike

+0

Buna neyin sebep olduğunu görmek zor. Bunu bir test uygulaması olarak paketlemeyi ve bugreporter.apple.com'da bir radarı göndermeyi öneririm. Ya da yedek bir DTS olayınız varsa, bir iş bulmak umuduyla bunları çalıştırın. –

cevap

0

Sorun, görüntü yönlendirmesinden kaynaklanmaktadır.
Her UIImage, CGImage için bu bilgiyi kaybettiğinizde, ekrana işlendiğinde, bir kez görüntülenmek üzere UIImage üzerinde uygulanması gereken yönlendirmeyi tanımlayan bir -imageOrientation özelliği içerir.
Sağlanan meta veri sözlüğünde kameranın görüntüsünü elde ederseniz, EXIF ​​yönelimi de vardır, bu nedenle verilerinizin nereden geldiğini bağlıdır.
Blogumda, fotoğraf makinesi kameradan geliyorsa, bu konuda bir article yazdım ve bunları nasıl kullanacağımı doğru yazdım.
Hızlı bir çözüm CGImage özelliğini okuyabilir ve -imageOrientation özelliğine göre bir dönüşüm uygulayabilir. Farklı yollar, Bu parçacık here alınır here ve here

bulabilirsiniz,

- (UIImage *)croppedImageInRect:(CGRect)rect 
{ 
    double (^rad)(double) = ^(double deg) { 
     return deg/180.0 * M_PI; 
    }; 

    CGAffineTransform rectTransform; 
    switch (self.imageOrientation) { 
     case UIImageOrientationLeft: 
      rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -self.size.height); 
      break; 
     case UIImageOrientationRight: 
      rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -self.size.width, 0); 
      break; 
     case UIImageOrientationDown: 
      rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -self.size.width, -self.size.height); 
      break; 
     default: 
      rectTransform = CGAffineTransformIdentity; 
    }; 
    rectTransform = CGAffineTransformScale(rectTransform, self.scale, self.scale); 

    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], CGRectApplyAffineTransform(rect, rectTransform)); 
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; 
    CGImageRelease(imageRef); 

    return result; 
} 
+0

Görüntü yöneliminin neden sorun olacağından emin değilim? Gördüğüm görüntülerin hiçbiri hiç döndürülmedi. Her şey doğru yönde olmuştur. Sadece bölümleri değiştirildi. Çözümünüzü test edip yardımcı olup olmadığına bakacağım. – Mike

+0

Ben de emin değilim, ancak diskin üzerindeki görüntülerin kaydedilmesinden kaynaklanan bir dönüşüm değişikliği yaşamadım. Görüntülerin döndüğünü söyledin, bu eğitimli bir tahmin. UIimageView, varsayılan UIImageRotationUp öğesinden farklı olduğunu fark ederse dönüşü hesaba katar, bu nedenle ekranda her şeyi düzeltmeyi görür, ancak CGImage'ın döndürme özelliği yoktur, bu yüzden farklı yönlerde bazılarını görüyorsunuz. Ve UIImageOrientationUp farklı bir şey görürseniz, her UIImage -imageOrientationProperty ve daha kolay yolu, bu sorun olacaktır. – Andrea

İlgili konular