Создавая и Используя источники изображения

Источник изображения абстрагирует задачу доступа к данным и избавляет от необходимости Вас управлять данными через необработанный буфер памяти. Источник изображения может содержать больше чем одно изображение, изображения миниатюр, свойства для каждого изображения и файл образа. Когда Вы работаете с данными изображения и Вашим выполнением приложения в OS X v10.4 или позже, источники изображения являются предпочтительным способом переместить данные изображения в Ваше приложение. После создания a CGImageSource объект, можно получить изображения, миниатюры, свойства изображения и другие данные изображения с помощью функций, описанных в Ссылке CGImageSource.

Создание изображения от источника изображения

Одна из наиболее распространенных задач, Вы выполните с Изображением платформу I/O, состоит в том, чтобы создать изображение из источника изображения, подобного тому, что показано в Перечислении 2-1. Этот пример показывает, как создать источник изображения из пути и затем извлечь изображение. При создании объекта источника изображения можно обеспечить подсказку относительно формата файла источника изображения.

При создании изображения из источника изображения необходимо указать индекс, и можно обеспечить словарь свойств (пары ключ/значение) для указания таких вещей как, создать ли миниатюру или позволить кэшироваться. Ссылка CGImageSource и ключи Списка ссылок CGImageProperties и ожидаемый тип данных значения для каждого ключа.

Необходимо предоставить индексное значение, потому что некоторые форматы файла образа позволяют повторным изображениям находиться в том же исходном файле. Для файла источника изображения, содержащего только одно изображение, передачу 0. Можно узнать число изображений в файле источника изображения путем вызывания функции CGImageSourceGetCount.

Перечисление 2-1  , Создающее изображение из источника изображения

CGImageRef MyCreateCGImageFromFile (NSString* path)
{
    // Get the URL for the pathname passed to the function.
    NSURL *url = [NSURL fileURLWithPath:path];
    CGImageRef        myImage = NULL;
    CGImageSourceRef  myImageSource;
    CFDictionaryRef   myOptions = NULL;
    CFStringRef       myKeys[2];
    CFTypeRef         myValues[2];
 
    // Set up options if you want them. The options here are for
    // caching the image in a decoded form and for using floating-point
    // values if the image format supports them.
    myKeys[0] = kCGImageSourceShouldCache;
    myValues[0] = (CFTypeRef)kCFBooleanTrue;
    myKeys[1] = kCGImageSourceShouldAllowFloat;
    myValues[1] = (CFTypeRef)kCFBooleanTrue;
    // Create the dictionary
    myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
                   (const void **) myValues, 2,
                   &kCFTypeDictionaryKeyCallBacks,
                   & kCFTypeDictionaryValueCallBacks);
    // Create an image source from the URL.
    myImageSource = CGImageSourceCreateWithURL((CFURLRef)url, myOptions);
    CFRelease(myOptions);
    // Make sure the image source exists before continuing
    if (myImageSource == NULL){
        fprintf(stderr, "Image source is NULL.");
        return  NULL;
    }
    // Create an image from the first item in the image source.
    myImage = CGImageSourceCreateImageAtIndex(myImageSource,
                                           0,
                                           NULL);
 
    CFRelease(myImageSource);
    // Make sure the image exists before continuing
    if (myImage == NULL){
         fprintf(stderr, "Image not created from image source.");
         return NULL;
    }
 
    return myImage;
}

Создание изображения миниатюр от источника изображения

Некоторые файлы источника изображения содержат изображения миниатюр, которые можно получить. Если миниатюры уже не присутствуют, Изображение, I/O дает Вам опцию создания их. Можно также указать максимальный размер миниатюры и применить ли преобразование к изображению миниатюр.

Перечисление 2-2 показывает, как создать источник изображения из данных, установить словарь, содержащий опции, связанные с миниатюрой, и затем создайте изображение миниатюр. Вы используете kCGImageSourceCreateThumbnailWithTransform ключ, чтобы указать, должно ли изображение миниатюр поворачиваться и масштабироваться для соответствия ориентации и попиксельной пропорции полного образа.

Перечисление 2-2  , Создающее изображение миниатюр

CGImageRef MyCreateThumbnailImageFromData (NSData * data, int imageSize)
{
    CGImageRef        myThumbnailImage = NULL;
    CGImageSourceRef  myImageSource;
    CFDictionaryRef   myOptions = NULL;
    CFStringRef       myKeys[3];
    CFTypeRef         myValues[3];
    CFNumberRef       thumbnailSize;
 
   // Create an image source from NSData; no options.
   myImageSource = CGImageSourceCreateWithData((CFDataRef)data,
                                               NULL);
   // Make sure the image source exists before continuing.
   if (myImageSource == NULL){
        fprintf(stderr, "Image source is NULL.");
        return  NULL;
   }
 
   // Package the integer as a  CFNumber object. Using CFTypes allows you
   // to more easily create the options dictionary later.
   thumbnailSize = CFNumberCreate(NULL, kCFNumberIntType, &imageSize);
 
   // Set up the thumbnail options.
   myKeys[0] = kCGImageSourceCreateThumbnailWithTransform;
   myValues[0] = (CFTypeRef)kCFBooleanTrue;
   myKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
   myValues[1] = (CFTypeRef)kCFBooleanTrue;
   myKeys[2] = kCGImageSourceThumbnailMaxPixelSize;
   myValues[2] = (CFTypeRef)thumbnailSize;
 
   myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
                   (const void **) myValues, 2,
                   &kCFTypeDictionaryKeyCallBacks,
                   & kCFTypeDictionaryValueCallBacks);
 
  // Create the thumbnail image using the specified options.
  myThumbnailImage = CGImageSourceCreateThumbnailAtIndex(myImageSource,
                                          0,
                                          myOptions);
  // Release the options dictionary and the image source
  // when you no longer need them.
  CFRelease(thumbnailSize);
  CFRelease(myOptions);
  CFRelease(myImageSource);
 
   // Make sure the thumbnail image exists before continuing.
   if (myThumbnailImage == NULL){
         fprintf(stderr, "Thumbnail image not created from image source.");
         return NULL;
   }
 
   return myThumbnailImage;
}

Инкрементно загрузка изображения

Если Вы имеете очень большое изображение или загружаете данные изображения по сети, можно хотеть создать инкрементный источник изображения так, чтобы можно было нарисовать данные изображения, поскольку Вы накапливаете его. Необходимо выполнить следующие задачи загрузить изображение инкрементно из объекта CFData:

  1. Создайте объект CFData для накопления данных изображения.

  2. Создайте инкрементный источник изображения путем вызывания функции CGImageSourceCreateIncremental.

  3. Добавьте данные изображения к объекту CFData.

  4. Вызовите функцию CGImageSourceUpdateData, передача CFData возражает и булево значение (bool тип данных), который указывает, содержит ли параметр данных все изображение, или просто частичные данные изображения. В любом случае параметр данных должен содержать все данные файла образа, накопленные до той точки.

  5. При накоплении достаточного количества данных изображения создайте изображение путем вызова CGImageSourceCreateImageAtIndex, нарисуйте частичное изображение, и затем выпустите его.

  6. Проверьте, чтобы видеть, есть ли у Вас все данные для изображения путем вызывания функции CGImageSourceGetStatusAtIndex. Если изображение завершено, эта функция возвраты kCGImageStatusComplete. Если изображение не завершено, повторите шаги 3 и 4, пока это не.

  7. Выпустите инкрементный источник изображения.

Отображение свойств изображения

Цифровые фотографии тегируются с богатством информации об изображении — размеры изображения, разрешение, ориентация, цветовой профиль, апертура, измеряя режим, фокусное расстояние, дату создания, ключевые слова, заголовок, и многое другое. Эта информация чрезвычайно полезна для обработки изображения и редактирования, но только если данные представлены в пользовательском интерфейсе. Несмотря на то, что CGImageSourceCopyPropertiesAtIndex функция получает словарь всех свойств, связанных с изображением в источнике изображения, необходимо будет записать код, пересекающий тот словарь, чтобы получить и затем вывести на экран ту информацию.

В этом разделе Вы внимательно изучите подпрограмму от OS X пример кода ImageApp, который является приложением дисплея изображения, которое можно загрузить и экспериментировать с. Одна из функций примера кода ImageApp является окном Info изображения, выводящим на экран изображение миниатюр и свойства изображения для в настоящее время активного изображения, как показано на рисунке 2-1.

  Окно An Info рисунка 2-1, выводящее на экран свойства изображения
An Info panel that displays image properties

Можно смотреть на ImageInfoPanel.h и ImageInfoPanel.m файлы для всех подробных данных реализации этой панели; необходимо будет также смотреть на файл пера для проекта видеть, как устанавливаются окно и привязка. Для понимания то, как можно использовать функции CGImageSource для поддержки приложения редактирования изображение смотрите на Перечисление 2-3. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления. (Следует иметь в виду, что эта подпрограмма не является автономной подпрограммой — Вы не можете просто вставить ее в свою собственную программу. Это - выборка от примера кода ImageApp.)

Перечисление 2-3  подпрограмма, создающая источник изображения и получающая свойства

 
- (void) setURL:(NSURL*)url
{
    if ([url isEqual:mUrl])
        return;
 
    mUrl = url;
 
    CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL); // 1
    if (source)
    {
        NSDictionary* props =
           (NSDictionary*) CGImageSourceCopyPropertiesAtIndex(source, 0, NULL); // 2
        [mTree setContent:[self propTree:props]]; // 3
        NSDictionary* thumbOpts = [NSDictionary dictionaryWithObjectsAndKeys:
            (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
            (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent,
            [NSNumber numberWithInt:128], (id)kCGImageSourceThumbnailMaxPixelSize,
            nil]; // 4
        CGImageRef image = CGImageSourceCreateThumbnailAtIndex(source, 0,
                                      (CFDictionaryRef)thumbOpts); // 5
        [mThumbView setImage:image]; // 6
        CGImageRelease(image); // 7
        [mFilePath setStringValue:[mUrl path]]; // 8
 
        NSString* uti = (NSString*)CGImageSourceGetType(source); // 9
        [mFileType setStringValue:[NSString stringWithFormat:@"%@\n%@",
                        ImageIOLocalizedString(uti), uti]]; // 10
 
        CFDictionaryRef fileProps = CGImageSourceCopyProperties(source, nil); // 11
        [mFileSize setStringValue:[NSString stringWithFormat:@"%@ bytes",
            (id)CFDictionaryGetValue(fileProps, kCGImagePropertyFileSize)]]; // 12
    }
    else  // 13
    {
        [mTree setContent:nil];
        [mThumbView setImage:nil];
        [mFilePath setStringValue:@""];
        [mFileType setStringValue:@""];
        [mFileSize setStringValue:@""];
    }
}

Вот то, что делает код:

  1. Создает объект источника изображения из URL, переданного подпрограмме.

  2. Копирует свойства для изображения, расположенного в индексном расположении 0. Некоторые форматы файла образа могут поддерживать больше чем одно изображение, но этот пример принимает единственное изображение (или что изображение интереса всегда является первым в файле). CGImageSourceCopyPropertiesAtIndex функционируйте возвращает объект CFDictionary. Здесь, код снимает CFDictionary в качестве NSDictionary объект, поскольку эти типы данных являются взаимозаменяемыми (иногда называемый бесплатными соединенный мостом).

    Словарь это возвращается, содержит свойства, которые являются парами ключ/значение. Однако некоторые значения являются самостоятельно словарями, содержащими свойства. Смотрите на рисунок 2-1, и Вы будете видеть не только простые пары ключ/значение (такие как RGB цветовой модели), но и Вы будете также видеть свойства Exif, Свойства IPTC, Свойства JFIF и Свойства TIFF, каждое из которых является словарем. Щелчок по треугольнику раскрытия для одного из этих дисплеев свойства в том словаре. Необходимо будет получить эти словари и их свойства, таким образом, они смогут быть выведены на экран соответственно в панели Info. Это - то, что выполняет следующий шаг.

  3. Свойства выдержек из словаря и устанавливают их в древовидный контроллер. Если Вы смотрите на ImageInfoPanel.h файл, Вы будете видеть что mTree переменная NSTreeController объект, который является выходом в Интерфейсном Разработчике. Этот контроллер управляет деревом объектов. В этом случае объекты являются свойствами изображения.

    propTree: метод предоставлен в ImageInfoPanel.m файл. Это - цель, должен пересечь словарь свойства, полученный на предыдущем шаге, извлечь свойства изображения и создать массив, это связывается с NSTreeController объект.

    Свойства появляются в таблице ключей и значений на рисунке 2-1.

  4. Устанавливает словарь опций использовать при создании изображения из источника изображения. Вспомните, что опции передаются в словаре. Панель Info, показанная на рисунке 2-1, выводит на экран изображение миниатюр. Код здесь устанавливает опции, создающие миниатюру, поворачивающуюся и масштабирующуюся к той же ориентации и форматному соотношению полного образа. Если миниатюра уже не существует, каждый создается, и ее максимальный размер пикселя 128 на 128 пикселей.

  5. Создает изображение миниатюр из первого изображения в источнике изображения, израсходовав набор опций на предыдущем шаге.

  6. Устанавливает изображение миниатюр в представление в панели Info.

  7. Выпускает изображение; это больше не необходимо.

  8. Извлекает путь из URL, передал методу и устанавливает строку в текстовое поле, это связывается с панелью Info. Это - текстовое поле Path на рисунке 2-1.

  9. Получает универсальный идентификатор типа источника изображения. (Это может отличаться от типа изображений в источнике.)

  10. Вызывает функцию для получения локализованной строки для UTI (ImageIOLocalizedString объявляется в ImagePanel.m) и затем устанавливает строку в текстовое поле, это связывается с панелью Info. Это - текстовое поле Type на рисунке 2-1.

  11. Получает словарь свойств, связанных с источником изображения. Эти свойства применяются к контейнеру (такому как размер файла), не обязательно отдельные изображения в источнике изображения.

  12. Получает значение размера файла из словаря источника изображения, полученного на предыдущем шаге, затем устанавливает связанную строку в текстовое поле, это связывается с панелью Info. Это - текстовое поле Size, показанное на рисунке 2-1.

  13. Если источник не создается, удостоверяется, что все поля в пользовательском интерфейсе отражают тот факт.