2008-10-29 12 views
13

Objetivo: tomar un UIImage, recortar un cuadrado en el medio, cambiar el tamaño del cuadrado a 320x320 píxeles, cortar la imagen en 16 imágenes de 80x80, guardar las 16 imágenes en una matriz.Recortar un UIImage en iPhone

Aquí está mi código:

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]]; 
} 

el código funciona correctamente cuando el original (la variable imagen) tiene su dimensión más pequeña, ya sea mayor o menor que 320 píxeles. Cuando es exactamente 320, las imágenes resultantes de 80x80 son casi totalmente negras, algunas con algunos píxeles en los bordes que pueden (realmente no puedo decir) ser de la imagen original.

He probado mediante la visualización de la imagen completa tanto de forma directa:

[UIImage imageWithCGImage:finalImage]; 

e indirectamente:

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

En ambos casos, la pantalla trabajó. Los problemas solo surgen cuando intento cortar una parte de la imagen.

Respuesta

5

Después de un poco más de experimentación, encontré la siguiente solución (aún no sé por qué no funcionó como se escribió originalmente). Pero de todos modos, el corte funciona después de que el código de ajuste de tamaño se coloca incluso cuando cambiar el tamaño es innecesario:

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(); 
} 

Cualquiera tiene alguna pista ¿POR QUÉ está pasando esto?

P.S. Sí, if/else ya no es necesario aquí. Quitándolo antes de Sabía que iba a funcionar sería estúpido, sin embargo.

1

Solo por curiosidad, ¿por qué hiciste tu matriz mutable con un límite de 0 cuando sabes que vas a poner 16 cosas en él?

Bueno, aparte de eso, he probado las técnicas básicas que usaste para cambiar el tamaño y cortar (no tuve que cortar, porque estoy trabajando con imágenes que ya son cuadradas) y no puedo reproducir tu problema en el simulador. Es posible que desee intentar dividir su código en tres funciones separadas (recortar a cuadrado, cambiar el tamaño y cortar en trozos) y luego probar los tres por separado para que pueda averiguar cuál de los tres pasos está causando los problemas (es decir, las imágenes de entrada que has manipulado en un programa de gráficos normal en lugar de usar el objetivo c y luego inspeccionar lo que obtienes de nuevo!).

Voy a adjuntar mis versiones de las funciones de cambio de tamaño y división a continuación, que con suerte serán útiles. Fue agradable tener sus versiones para mirar, ya que no tuve que encontrar todos los métodos por mí mismo por una vez. :)

Como nota, la matriz bidimensional mencionada es mi propia clase construida a partir de NSMutableArrays, pero podría implementar fácilmente su propia versión o usar una NSMutableArray plana en su lugar. ;)

// 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

Cuestiones relacionadas