Подтвердить что ты не робот

Создание глубокой копии UIImage

Мой класс содержит свойство UIImage, которое я хочу использовать в качестве свойства "копировать" любыми внешними клиентами, обращающимися к нему. Но когда я пытаюсь сделать копию в своем настраиваемом сетевом устройстве, я получаю ошибку времени выполнения 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];
    }
}
4b9b3361

Ответ 1

Вот как это сделать:

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

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

Если вы объясните немного больше того, что вы пытаетесь сделать, возможно, есть другой способ его достижения.

Ответ 3

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

Говоря о глубоких копиях, мы должны сначала понять, что 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

Ответ 4

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

Ответ 5

 CGImageRef newCgIm = CGImageCreateCopy(oldImage.CGImage);
 UIImage *newImage = [UIImage imageWithCGImage:newCgIm scale:oldImage.scale 
                     orientation:oldImage.imageOrientation];