2008-10-29 17 views
13

Ziel: nehmen Sie ein UIImage, ein Quadrat in der Mitte ausschneiden, Größe des Quadrats zu 320x320 Pixel ändern, das Bild in 16 80x80 Bilder schneiden, speichern Sie die 16 Bilder in einem Array.Schneiden eines UIImage auf dem iPhone

Hier ist mein Code:

CGImageRef originalImage, resizedImage, finalImage, tmp; 
float imgWidth, imgHeight, diff; 
UIImage *squareImage, *playImage; 
NSMutableArray *tileImgArray; 
int r, c; 

originalImage = [image CGImage]; 

imgWidth = image.size.width; 
imgHeight = image.size.height; 
diff = fabs(imgWidth - imgHeight); 

if(imgWidth > imgHeight){ 
    resizedImage = CGImageCreateWithImageInRect(originalImage, CGRectMake(floor(diff/2), 0, imgHeight, imgHeight)); 
}else{ 
    resizedImage = CGImageCreateWithImageInRect(originalImage, CGRectMake(0, floor(diff/2), imgWidth, imgWidth)); 
} 
CGImageRelease(originalImage); 

squareImage = [UIImage imageWithCGImage:resizedImage];  
if(squareImage.size.width != squareImage.size.height){ 
    NSLog(@"image cutout error!"); 
    //*code to return to main menu of app, irrelevant here 
}else{ 
    float newDim = squareImage.size.width; 
    if(newDim != 320.0){ 
     CGSize finalSize = CGSizeMake(320.0, 320.0); 
     UIGraphicsBeginImageContext(finalSize); 
     [squareImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)]; 
     playImage = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
    }else{ 
     playImage = squareImage; 
    } 
} 

finalImage = [playImage CGImage]; 
tileImgArray = [NSMutableArray arrayWithCapacity:0]; 
for(int i = 0; i < 16; i++){ 
    r = i/4; 
    c = i%4; 
    //* 
    tmp = CGImageCreateWithImageInRect(finalImage, CGRectMake(c*tileSize, r*tileSize, tileSize, tileSize)); 
    [tileImgArray addObject:[UIImage imageWithCGImage:tmp]]; 
} 

Der Code funktioniert einwandfrei, wenn das Original (die Variable Bild) hat seine kleineren Dimension entweder größer oder kleiner als 320 Pixel. Wenn es genau 320 ist, sind die resultierenden 80x80-Bilder fast vollständig schwarz, einige mit ein paar Pixeln an den Rändern, die (ich kann es nicht wirklich sagen) vom Originalbild stammen.

I durch Anzeige der Vollbild sowohl direkt getestet:

[UIImage imageWithCGImage:finalImage]; 

Und indirekt:

[UIImage imageWithCGImage:CGImageCreateWithImageInRect(finalImage, CGRectMake(0, 0, 320, 320))]; 

In beiden Fällen war die Anzeige. Die Probleme treten nur auf, wenn ich versuche, einen Teil des Bildes auszuschneiden.

Antwort

5

Nach ein paar weiteren Experimenten fand ich die folgende Lösung (ich weiß immer noch nicht, warum es nicht wie ursprünglich geschrieben funktioniert hat). Aber trotzdem funktioniert das Slicing nach dem Resize-Code auch wenn Größenanpassung ist nicht notwendig:

if(newDim != 320.0){ 
      CGSize finalSize = CGSizeMake(320.0, 320.0); 
      UIGraphicsBeginImageContext(finalSize); 
      [squareImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)]; 
      playImage = UIGraphicsGetImageFromCurrentImageContext(); 
      UIGraphicsEndImageContext(); 
}else{ 
      CGSize finalSize = CGSizeMake(320.0, 320.0); 
      UIGraphicsBeginImageContext(finalSize); 
      [squareImage drawInRect:CGRectMake(0, 0, finalSize.width, finalSize.height)]; 
      playImage = UIGraphicsGetImageFromCurrentImageContext(); 
      UIGraphicsEndImageContext(); 
} 

Jeder hat eine Ahnung WARUM ist das so?

P.S. Ja, wenn/sonst wird hier nicht mehr benötigt. Es zu entfernen vor Ich wusste, dass es funktionieren würde, wäre aber dumm.

1

Nur aus Neugier, warum hast du dein veränderbares Array mit 0 gebunden, wenn du weißt, dass du 16 Sachen hineinlegst?

Nun, abgesehen davon habe ich die grundlegenden Techniken ausprobiert, die Sie für Größenanpassung und Slicing verwendet haben (ich musste nicht zuschneiden, weil ich mit Bildern arbeite, die bereits quadratisch sind) und ich kann nicht reproduzieren dein Problem im Simulator. Sie können versuchen, Ihren Code in drei separate Funktionen zu zerlegen (zuschneiden, verkleinern und in Stücke schneiden) und dann die drei separat testen, um herauszufinden, welcher der drei Schritte die Probleme verursacht (dh Bilder eingeben, die Sie haben in einem normalen Grafikprogramm manipuliert, anstatt objektive c zu verwenden und dann zu inspizieren, was Sie zurückbekommen!).

Ich werde meine Versionen der Größenänderung und Slice-Funktionen unten anhängen, die hoffentlich hilfreich sein werden. Es war schön, dass man sich die Versionen anschaut, da ich nicht alle Methoden für sich alleine finden musste. :)

Nur als eine Anmerkung, das zweidimensionale Array erwähnt ist meine eigene Klasse aus NSMutableArrays, aber Sie könnten leicht Ihre eigene Version oder verwenden Sie eine flache NSMutableArray statt. ;)

// cut the given image into a grid of equally sized smaller images 
// this assumes that the image can be equally divided in the requested increments 
// the images will be stored in the return array in [row][column] order 
+ (TwoDimensionalArray *) chopImageIntoGrid : (UIImage *) originalImage : (int) numberOfRows : (int) numberOfColumns 
{ 
// figure out the size of our tiles 
int tileWidth = originalImage.size.width/numberOfColumns; 
int tileHeight = originalImage.size.height/numberOfRows; 

// create our return array 
TwoDimensionalArray * toReturn = [[TwoDimensionalArray alloc] initWithBounds : numberOfRows 
                      : numberOfColumns]; 

// get a CGI image version of our image 
CGImageRef cgVersionOfOriginal = [originalImage CGImage]; 

// loop to chop up each row 
for(int row = 0; row < numberOfRows ; row++){ 
    // loop to chop up each individual piece by column 
    for (int column = 0; column < numberOfColumns; column++) 
    { 
     CGImageRef tempImage = 
       CGImageCreateWithImageInRect(cgVersionOfOriginal, 
              CGRectMake(column * tileWidth, 
                 row * tileHeight, 
                 tileWidth, 
                 tileHeight)); 
     [toReturn setObjectAt : row : column : [UIImage imageWithCGImage:tempImage]]; 
    } 
} 

// now return the set of images we created 
return [toReturn autorelease]; 
} 

// this method resizes an image to the requested dimentions 
// be a bit careful when using this method, since the resize will not respect 
// the proportions of the image 
+ (UIImage *) resize : (UIImage *) originalImage : (int) newWidth : (int) newHeight 
{ 
// translate the image to the new size 
CGSize newSize = CGSizeMake(newWidth, newHeight); // the new size we want the image to be 
UIGraphicsBeginImageContext(newSize); // downside: this can't go on a background thread, I'm told 
[originalImage drawInRect : CGRectMake(0, 0, newSize.width, newSize.height)]; 
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); // get our new image 
UIGraphicsEndImageContext(); 

// return our brand new image 
return newImage; 
} 

Eva Schiffer