Создание глубокой копии UIImage - PullRequest
13 голосов
/ 23 октября 2010

Мой класс содержит свойство UIImage, которое я хочу использовать в качестве свойства 'copy' любыми внешними клиентами, обращающимися к нему.Но, когда я пытаюсь сделать копию в моем пользовательском установщике, я получаю ошибку времени выполнения о том, что UIImage не поддерживает copyWithZone.Итак, что является хорошим способом обеспечить соблюдение правильной политики владения?

// declared in the interface as:
@property (nonatomic, readonly, copy) UIImage *personImage;

// class implementation
- (void)setPersonImage:(UIImage *)newImage
{
    if (newImage != personImage) 
    {
        [personImage release];

        // UIImage doesn't support copyWithZone
        personImage = [newImage copy];
    }
}

Ответы [ 5 ]

14 голосов
/ 08 апреля 2012

Вот способ сделать это:

UIImage *imageToCopy = <# Your image here #>;
UIGraphicsBeginImageContext(imageToCopy.size);
[imageToCopy drawInRect:CGRectMake(0, 0, imageToCopy.size.width, imageToCopy.size.height)];
UIImage *copiedImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();   

Причина, по которой мне это нужно, в том, что у меня была переменная изображения, инициализированная с imageWithContentsOfFile:, и я хотел иметь возможность удалить файл с диска, носохранить переменную изображения.Я был удивлен, обнаружив, что при удалении файла переменная изображения сходит с ума.Он отображал странные случайные данные, даже если они были инициализированы до удаления файла.Когда я сначала глубоко копирую, все работает нормально.

2 голосов
/ 07 февраля 2016

Глубокая копия

Говоря о глубоких копиях, мы должны сначала понять, что UIImage - это контейнер. На самом деле он не содержит данных изображения. Базовые данные могут быть CIImage или CGImage. В большинстве случаев вспомогательными данными является CGImage, который, в свою очередь, является структурой обертки, а копирование CGImage - это просто копирование метаданных, а не базовых данных. Если вы хотите скопировать исходные данные, вы можете нарисовать изображение в контексте или получить копию данных в формате PNG.

UIImagePNGRepresentation

Создание игровой площадки со следующим демонстрирует метод.

let zebra = UIImage(named: "an_image_of_a_zebra")
print(zebra?.CGImage) // check the address
let shallowZebra = UIImage(CGImage: zebra!.CGImage!) 
print(shallowZebra.CGImage!) // same address

let zebraData = UIImagePNGRepresentation(zebra!)
let newZebra = UIImage(data: zebraData!)
print(newZebra?.CGImage) // new address
1 голос
/ 23 октября 2010

Зачем вам нужна семантика копирования?UIImage является неизменным, поэтому нет смысла устанавливать политику копирования.Вам просто нужна политика копирования, если есть риск, что кто-то другой может изменить изображение на вас.Так как UIImage является неизменяемым, риска этого не возникает, поэтому свойство сохранения отличноэто.

0 голосов
/ 20 ноября 2014
 CGImageRef newCgIm = CGImageCreateCopy(oldImage.CGImage);
 UIImage *newImage = [UIImage imageWithCGImage:newCgIm scale:oldImage.scale 
                     orientation:oldImage.imageOrientation];
0 голосов
/ 13 августа 2014

Поскольку изображение само по себе является указателем, необходимо создать контекст изображения, нарисовать изображение в контексте и затем получить исходное изображение из контекста.Может быть, вам нужно использовать UIImage.CGImage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...