Как уменьшить изображение в iOS, сглаженное, но не мягкое?

Я попробовал популярную категорию UIImage+Resize с различными настройками интерполяции. Я пробовал масштабировать с помощью методов CG и CIFilters. Тем не менее, я никогда не могу получить уменьшенное изображение, которое не выглядит слегка размытым в фокусе и не содержит зубчатых артефактов. Есть ли другое решение или сторонняя библиотека, которая позволила бы мне получить очень четкое изображение?

Это должно быть возможно на iPhone, потому что, например, приложение «Фотографии» будет показывать четкое изображение, даже если сжать его, чтобы уменьшить.


person akaru    schedule 02.02.2012    source источник


Ответы (4)


Вы сказали CG, но не уточнили свой подход.

Использование контекста рисования или растрового изображения:

CGContextSetInterpolationQuality(gtx, kCGInterpolationHigh);
CGContextSetShouldAntialias(gtx, true); << default varies by context type
CGContextDrawImage(gtx, rect, image);

и убедитесь, что ваши представления и их слои не изменяют размер изображения снова. У меня были хорошие результаты с этим. Возможно, другие представления влияют на ваше представление или контекст. Если это не выглядит хорошо, попробуйте изолированно, чтобы проверить здравомыслие, не искажает ли что-то ваше представление/изображение.

Если вы рисуете в растровое изображение, вы создаете растровое изображение с целевыми размерами, а затем рисуете на него.

В идеале вы сохраните соотношение сторон.

Также обратите внимание, что это может сильно нагружать ЦП — многократное рисование/масштабирование в HQ будет стоить много времени, поэтому вместо этого вы можете создать копию с измененным размером (используя CGBitmapContext).

person justin    schedule 16.02.2012
comment
Я использовал графический контекст пользовательского интерфейса и рисовал через drawInRect или drawAtPoint, а также это. Однако вы заставили меня еще раз взглянуть на мой код, и я понял, что на самом деле это связано с другим аспектом моего кода. - person akaru; 17.02.2012
comment
да - это хорошая идея, чтобы четко указать настройки графических контекстов, потому что они и другие аспекты графической системы могут сильно различаться. - person justin; 17.02.2012

Вот процедура, которую я написал для этого. Есть немного мягкого фокуса, хотя в зависимости от того, насколько вы масштабируете исходное изображение, это не так уж плохо. Я масштабирую программные снимки экрана.

- (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {

    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}
person scooter133    schedule 16.02.2012

CGContextSetInterpolationQuality — это то, что вам нужно.

Вам следует попробовать дополнения к этой категории http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

person Mugunth    schedule 16.02.2012

Когда изображение уменьшено, часто полезно применить некоторую резкость.

Проблема в том, что Core Image на iOS (пока) не реализует фильтры повышения резкости (CISharpenLuminance, CIUnsharpMask), поэтому вам придется создавать свои собственные. Или ворчать на Apple, пока они не внедрят эти фильтры и на iOS.

Тем не менее, Sharpen luminance и Unsharp mask являются довольно продвинутыми фильтрами, и в предыдущих проектах я обнаружил, что даже простое ядро ​​​​3x3 дает четко видимые и удовлетворительные результаты.

Следовательно, если вам хочется работать на уровне пикселей, вы можете получить данные изображения из графического контекста, побитовую маску перейти к значениям R, G и B и закодировать графику, как в 1999 году. Это будет это немного похоже на изобретение велосипеда.

Может быть, есть какие-то стандартные графические библиотеки, которые тоже могут это делать (ImageMagick?)

person Monolo    schedule 16.02.2012