2013-05-15 20 views
5

Saydam bir arka plana sahip bir UIImage alma ve kırpılacak en küçük dikdörtgeni belirleme stratejisi, yalnızca görünür görüntü verilerinin kalması için (görüntü, ek şeffaf arka planla birlikte) veriler dikdörtgensel değil)?Saydam arka plana sahip UIImage için kırpma dikdörtgenini belirleme

Ben, görünüm (MGImageUtilities ve NYXImagesKit dahil) görüntü işleme sınıfları ve kategorileriyle kullanıcı müdahalesi ve birkaç açık kaynak kütüphaneleri gerektiren denetleyicileri, başka bir şey kırpma bol henüz bir CGRect bir UIImage kırpma pek çok bilgi bulduk Benim özel problemimi çözer.

Şu anki uygulamam iOS 5.0'ı hedefliyor, dolayısıyla bu uygunluk en uygun olacak şekilde.

DÜZENLEME: Bu arada, kenar sınırlarını arayan satır ve sütunlardaki görüntü verilerinin en kötü durum senaryosunda her piksele bakarak kaba kuvvetten daha iyi bir yol olduğunu umuyorum.

cevap

9

https://gist.github.com/spinogrizz/3549921'u görme şansınız oldu mu?

Tam olarak ihtiyacınız olan şey gibi görünüyor. o kayıp değil sadece bu yüzden

, o sayfadan bir kopyası & yapıştır:

- (UIImage *) imageByTrimmingTransparentPixels { 
    int rows = self.size.height; 
    int cols = self.size.width; 
    int bytesPerRow = cols*sizeof(uint8_t); 

    if (rows < 2 || cols < 2) { 
     return self; 
    } 

    //allocate array to hold alpha channel 
    uint8_t *bitmapData = calloc(rows*cols, sizeof(uint8_t)); 

    //create alpha-only bitmap context 
    CGContextRef contextRef = CGBitmapContextCreate(bitmapData, cols, rows, 8, bytesPerRow, NULL, kCGImageAlphaOnly); 

    //draw our image on that context 
    CGImageRef cgImage = self.CGImage; 
    CGRect rect = CGRectMake(0, 0, cols, rows); 
    CGContextDrawImage(contextRef, rect, cgImage); 

    //summ all non-transparent pixels in every row and every column 
    uint16_t *rowSum = calloc(rows, sizeof(uint16_t)); 
    uint16_t *colSum = calloc(cols, sizeof(uint16_t)); 

    //enumerate through all pixels 
    for (int row = 0; row < rows; row++) { 
     for (int col = 0; col < cols; col++) 
     { 
      if (bitmapData[row*bytesPerRow + col]) { //found non-transparent pixel 
       rowSum[row]++; 
       colSum[col]++; 
      } 
     } 
    } 

    //initialize crop insets and enumerate cols/rows arrays until we find non-empty columns or row 
    UIEdgeInsets crop = UIEdgeInsetsMake(0, 0, 0, 0); 

    for (int i = 0; i<rows; i++) {  //top 
     if (rowSum[i] > 0) { 
      crop.top = i; break; 
     } 
    } 

    for (int i = rows; i >= 0; i--) {  //bottom 
     if (rowSum[i] > 0) { 
      crop.bottom = MAX(0, rows-i-1); break; 
     } 
    } 

    for (int i = 0; i<cols; i++) {  //left 
     if (colSum[i] > 0) { 
      crop.left = i; break; 
     } 
    } 

    for (int i = cols; i >= 0; i--) {  //right 
     if (colSum[i] > 0) { 
      crop.right = MAX(0, cols-i-1); break; 
     } 
    } 

    free(bitmapData); 
    free(colSum); 
    free(rowSum); 

    if (crop.top == 0 && crop.bottom == 0 && crop.left == 0 && crop.right == 0) { 
     //no cropping needed 
     return self; 
    } 
    else { 
     //calculate new crop bounds 
     rect.origin.x += crop.left; 
     rect.origin.y += crop.top; 
     rect.size.width -= crop.left + crop.right; 
     rect.size.height -= crop.top + crop.bottom; 

     //crop it 
     CGImageRef newImage = CGImageCreateWithImageInRect(cgImage, rect); 

     //convert back to UIImage 
     return [UIImage imageWithCGImage:newImage]; 
    } 
} 
+0

Swift 4'te, ama yeterince iyi çalışır. Teşekkürler. –

+0

Benim için çalıştı (Y) – Xeieshan

+1

Benim için çalışmıyor - ama umuyorum ki başka bir versiyonu yüzüyor… – Benjohn

-5

WWDC üzerinde CoreImage Slaytlar bakın. Cevabınız direkt.

0

burada Biraz çirkin

extension UIImage { 

func cropAlpha() -> UIImage { 

    let cgImage = self.cgImage!; 

    let width = cgImage.width 
    let height = cgImage.height 

    let colorSpace = CGColorSpaceCreateDeviceRGB() 
    let bytesPerPixel:Int = 4 
    let bytesPerRow = bytesPerPixel * width 
    let bitsPerComponent = 8 
    let bitmapInfo: UInt32 = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue 

    guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo), 
     let ptr = context.data?.assumingMemoryBound(to: UInt8.self) else { 
      return self 
    } 

    context.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: width, height: height)) 

    var minX = width 
    var minY = height 
    var maxX: Int = 0 
    var maxY: Int = 0 

    for x in 1 ..< width { 
     for y in 1 ..< height { 

      let i = bytesPerRow * Int(y) + bytesPerPixel * Int(x) 
      let a = CGFloat(ptr[i + 3])/255.0 

      if(a>0) { 
       if (x < minX) { minX = x }; 
       if (x > maxX) { maxX = x }; 
       if (y < minY) { minY = y}; 
       if (y > maxY) { maxY = y}; 
      } 
     } 
    } 

    let rect = CGRect(x: CGFloat(minX),y: CGFloat(minY), width: CGFloat(maxX-minX), height: CGFloat(maxY-minY)) 
    let imageScale:CGFloat = self.scale 
    let croppedImage = self.cgImage!.cropping(to: rect)! 
    let ret = UIImage(cgImage: croppedImage, scale: imageScale, orientation: self.imageOrientation) 

    return ret; 
} 

}

İlgili konular