конвертувати UIImage в NSData


170

Я використовую цей код у своїй програмі, який допоможе мені надіслати зображення.

Однак у мене є зображення із зображенням. У мене немає файлу в appbundle, але зображення є в моїй стороні. Як я можу змінити наведений нижче код? Може хто - небудь сказати мені , як я можу перетворити myimageв NSData?

// Attach an image to the email
NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"jpg"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:@"image/jpeg" fileName:@"rainy"];

2
UIImageJPEGRepresentation, UIImagePNGRepresentation обидва повертають nsdata зображення .....
Himanshu Agnihotri

Відповіді:


286

Спробуйте скористатись одним із наступних дій, залежно від формату зображення:

UIImageJPEGRepresentation

Повертає дані для вказаного зображення у форматі JPEG.

NSData * UIImageJPEGRepresentation (
   UIImage *image,
   CGFloat compressionQuality
);

Представлення UIImagePNGR

Повертає дані для вказаного зображення у форматі PNG

NSData * UIImagePNGRepresentation (
   UIImage *image
);

Тут документи .

Редагувати:

якщо ви хочете отримати доступ до необроблених байтів, що складають UIImage, ви можете використовувати такий підхід:

CGDataProviderRef provider = CGImageGetDataProvider(image.CGImage);
NSData* data = (id)CFBridgingRelease(CGDataProviderCopyData(provider));
const uint8_t* bytes = [data bytes];

Це дасть вам низький рівень представлення пікселів RGB зображення. (Пропустіть CFBridgingReleaseбіт, якщо ви не використовуєте ARC).


8
Чи є спосіб отримати дані в будь-якому форматі, в якому вони вже є?
devios1

1
Xcode пропонує мені використати, (id)CFBridgingRelease(CGDataProviderCopyData(provider))щоб взяти право власності на CDataRefповернутого CGDataProviderCopyDataв ARC.
mostruash

1
@mostruash: дякую, я змінив свою відповідь, щоб врахувати вашу пропозицію.
Серхіо

@sergio Я не маю досвіду з не-ARC Obj-C, і мені цікаво, чи dataдостатньо буде випуску або якщо все-таки буде витік пам'яті.
mostruash

1
Це не допоможе. Властивість CIImage встановлюється лише в тому випадку, якщо вона була ініціалізована з imageWithCIImage :. Також це не безпосередньо використовувані дані, а скоріше інший об’єкт подання зображення.
Король-Чарівник

161
NSData *imageData = UIImagePNGRepresentation(myImage.image);

4
Я використовую цей рядок, але це дуже повільно
user2128531

5
Зауважте, що imageFlags (наприклад, imageOrientation) втрачається при використанні UIImagePNGRepresentation. Ось чому переважна UIImageJPEGRepresentation.
Yony

26

Якщо у вас є зображення всередині UIImageView, наприклад, "myImageView", ви можете зробити наступне:

Перетворіть ваше зображення за допомогою UIImageJPEGRepresentation () або UIImagePNGRepresentation () таким чином:

NSData *data = UIImagePNGRepresentation(myImageView.image);
//or
NSData *data = UIImageJPEGRepresentation(myImageView.image, 0.8);
//The float param (0.8 in this example) is the compression quality 
//expressed as a value from 0.0 to 1.0, where 1.0 represents 
//the least compression (or best quality).

Ви також можете помістити цей код всередину блоку GCD та виконати в іншій потоці, показуючи UIActivityIndicatorView під час процесу ...

//*code to show a loading view here*

dispatch_queue_t myQueue = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_SERIAL);

dispatch_async(myQueue, ^{ 

    NSData *data = UIImagePNGRepresentation(myImageView.image);
    //some code....

    dispatch_async( dispatch_get_main_queue(), ^{
        //*code to hide the loading view here*
    });
});

24

Створіть посилання на зображення ....

UIImage *rainyImage = [UIImage imageNamed:@"rainy.jpg"];

відображення зображення у вікні зображення ... Imagedisplay - це посилання на перегляд зображення:

imagedisplay.image = rainyImage;

перетворити його в NSDataпроходження UIImageпосилання та забезпечити якість стиснення у плаваючих значеннях:

NSData *imgData = UIImageJPEGRepresentation(rainyImage, 0.9);

2

Рішення в Swift 4

extension UIImage {
    var data : Data? {
      return cgImage?.dataProvider?.data as Data?
    }
}

Як cgImage.dataProviderкодуються дані? Він, схоже, відрізняється від даних UIImagePNGRepresentationта UIImageJPEGRepresentationтому, що його не можна використовувати для створення подібного зображення UIImage(data: imageData).
Мануель

@Manuel Не впевнений. Я щойно перетворив синтаксис із відповіді Серхіо. Серхіо, певно, знав би краще.
Чарлтон Проватас

@Manuel Я припускаю, що за допомогою API CoreGraphics він надає зображення зображень нижчого рівня, ніж те, що UIImageJPEGRepresentationпередбачено. Але я вважаю, що це рішення зберігає початковий формат кодування, у якому було зображення, і не перекодує його.
Чарлтон Проватас

1

Використовуйте блок if-let із даними для запобігання збоїв програми та безпечного виконання коду, оскільки функція UIImagePNGRepresentation повертає необов'язкове значення.

if let img = UIImage(named: "TestImage.png") {
    if let data:Data = UIImagePNGRepresentation(img) {
       // Handle operations with data here...         
    }
}

Примітка: Дані - клас Swift 3. Використовуйте дані замість NSData за допомогою Swift 3

Загальні операції із зображенням (як png та jpg обидва):

if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
        if let data:Data = UIImagePNGRepresentation(img) {
               handleOperationWithData(data: data)     
        } else if let data:Data = UIImageJPEGRepresentation(img, 1.0) {
               handleOperationWithData(data: data)     
        }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}

Використовуючи розширення:

extension UIImage {

    var pngRepresentationData: Data? {
        return UIImagePNGRepresentation(img)
    }

    var jpegRepresentationData: Data? {
        return UIImageJPEGRepresentation(self, 1.0)
    }
}

*******
if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
      if let data = img.pngRepresentationData {
              handleOperationWithData(data: data)     
      } else if let data = img.jpegRepresentationData {
              handleOperationWithData(data: data)     
     }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}

0
- (void) imageConvert
{
     UIImage *snapshot = self.myImageView.image;
     [self encodeImageToBase64String:snapshot];
}    


call this method for image convert in base 64 
    -(NSString *)encodeImageToBase64String:(UIImage *)image
    {
        return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.