Frage

Ziel:. Nimmt eine UIImage, Ernte ein Quadrat in der Mitte aus, Wechsel Größe des Platzes 320x320 Pixel, schneiden Sie das Bild in 16 80x80 Bilder auf, die 16 Bilder in einem Array speichern

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 kleinere Dimension entweder größer oder kleiner als 320 Pixel. Wenn es genau 320 ist, sind die resultierenden 80x80 Bilder fast vollständig schwarz, an den Rändern einige mit wenigen Pixeln, kann (ich nicht wirklich sagen kann) aus dem Originalbild sein.

I getestet, indem die Vollbild angezeigt wird sowohl direkt:

[UIImage imageWithCGImage:finalImage];

Und indirekt:

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

In beiden Fällen war die Anzeige. Die Probleme entstehen nur, wenn ich einen Teil des Bildes zu schneiden heraus versuchen.

War es hilfreich?

Lösung

Nach weiterem Experimentieren finde ich die folgende Lösung (ich weiß immer noch nicht, warum es nicht wie ursprünglich geschrieben funktioniert, though.) Aber wie auch immer, funktioniert das Schneiden nach dem Resize-Code auch in Kraft gesetzt wird, wenn die Größenänderung 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();
}

Wer hat eine Ahnung, warum dies passiert?

P. S. Ja, wenn / sonst ist nicht mehr hier erforderlich. Entfernen Sie vor Ich wusste, es wäre dumm funktionieren würde, aber.

Andere Tipps

Nur aus Neugier, warum haben Sie machen Ihre änderbaren Array mit gefesselten von 0, wenn Sie wissen, dass Sie 16 Dinge darin ablegen werden?

Nun, abgesehen davon, habe ich die grundlegenden Techniken versucht, Sie zum Ändern der Größe und Schneiden verwendet (ich brauchte nicht zu beschneiden, weil ich mit Bildern arbeiten, die mich schon quadratisch sind), und ich bin nicht in der Lage Sie zu reproduzieren Problem im Simulator. Vielleicht möchten Sie den Code in drei separate Funktionen, um versuchen zu brechen (Ernte zu quadrieren, Größe ändern, und in Scheiben schneiden in Stücke) und testen Sie dann die separat drei, so dass Sie, welche der drei Schritten herausfinden können, die Probleme verursacht (dh. Eingangsbilder, die Sie haben statt mit Objective-c in einem normalen Grafikprogramm manipuliert und dann kontrollieren, was Sie wieder raus!).

Ich werde meine Versionen der Größe ändern und in Scheiben schneiden Funktionen unten anhängen, die hoffentlich hilfreich sein wird. Es war schön, Ihre Versionen zu haben, zu sehen, da ich nicht von mir, alle Methoden zu finden, habe einmal. :)

Nur als Anmerkung, die beiden genannten dimensionales Array ist meine eigene Klasse aus NSMutableArrays gebaut, aber man konnte leicht Ihre eigene Version implementieren oder eine flache NSMutableArray stattdessen verwenden. ;)

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top