Предположим, вы начинаете с UIImage, и вы хотите его обрезать. Наиболее распространенным методом является использование CGImageCreateWithImageInRect, чтобы получить CGImageRef и создать новый образ из него, как так:Как преобразовать объект UIImage, созданный из CGImageRef, в необработанные данные и обратно
CGRect cropRect = CGRectMake(x*width, y*height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
Теперь предположим, что вы позже должны преобразовать этот UIImage в объект NSData. Например, это произойдет, если вы хотите сохранить изображение на диске с помощью NSKeyedArchiver. Или вы можете получить NSData объект вне, выполнив следующие действия в явном виде:
NSData *imageData = UIImagePNGRepresentation(croppedImage);
Я сделал это, и позже я попытался реконструировать новый объект UIImage, выполнив:
UIImage *image = [UIImage imageWithData:imageData];
Я сделал это для серия из 48 изображений. Большинство из них были прекрасны, но после каждых 4 изображений следующие 2 были повреждены сверху и снизу каждого изображения. Если я вывожу конверсию в NSData и обратно, она работает нормально. Я также получаю ту же самую проблему, если я использую NSKeyedArchiver для записи массива изображений на диск (который, как я предполагаю, вызывает в UImagePNGRпредставлении в своей процедуре кодирования). Моя теория заключается в том, что это должно иметь какое-то отношение к тому, как я создаю изображения из CGImageRefs.
Каково обходное решение для этого? Я не могу понять, как поставить объект CGImageRefs в объект NSData, и я предпочел бы решение, которое правильно построит UIImage, чтобы оно могло быть сериализовано.
Edit:
Некоторые люди просили фактический код запускаемых, поэтому я добавляю его здесь
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);
}
}
Изображение из self.animationObject.image сетки изображений с numInX и и числовые изображения в каждом направлении. Я обрезаю каждое отдельное изображение из 2D-сетки и сохраняю их.
Позже я поместил изображения в изображение, чтобы оживить их. Вот код:
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];
}
Это все работает отлично на iPhone 6, но не работает на iPhone 5. Кроме того, кажется, только проблема, когда сетка изображений долго. Например, для примера я использую self.animationObject.image имеет numInY как 3 и numInX 2, а общий размер изображения - 1536x3072 (каждое мини-изображение 768x1024). Это два нижних изображения, которые имеют верх и низ.
Некоторые более полезные детали. У меня есть составные изображения, каждая из которых содержит 6 меньших изображений в сетке 2x3. Размер каждого изображения составляет 768x1024, поэтому общий размер составного изображения составляет 1536x3072. Это 5-й и 6-й изображения в каждом композите, которые имеют нижнюю и верхнюю половинки. Итак, что-то странное в CGImage, которое, возможно, связано с обрезкой до нижней части большого изображения? Опять же, я должен упомянуть, что это работает отлично, если UIImage не преобразован в NSData, а затем обратно. – Mike
Итак, в этом примере выше ширина 768, высота 1024 и разрывается, когда x равно 0 или 1, а y равно 2. Оно отлично работает, когда y равно 0 или 1. Это случай, когда CGImageCreateWithImageInRect просто не может справиться с большие изображения? – Mike
Его трудно понять, что может быть причиной этого. Я предлагаю упаковать это как тестовое приложение и подать радар на bugreporter.apple.com. Или, если у вас есть случай с DTS, чтобы сэкономить, запустите его в надежде на обход. –