2009-06-01 29 views
6

Tôi cần tạo biểu diễn chuỗi base64 của đối tượng ca cao NSImage. Cách tốt nhất để xử lý này là gì, tài liệu hướng dẫn của apple có vẻ hơi ngắn về chủ đề (hoặc tôi không thể tìm thấy nó). Mã hóa Base64 có vẻ khá phức tạp từ bên ngoài.NSImage to Base64

Mọi trợ giúp sẽ được đánh giá rất nhiều.

Cheers Alex

EDIT

NSArray *keys = [NSArray arrayWithObject:@"NSImageCompressionFactor"]; 
NSArray *objects = [NSArray arrayWithObject:@"1.0"]; 
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys]; 

NSImage *image = [[NSImage alloc] initWithContentsOfFile:[imageField stringValue]]; 
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]]; 
NSData *tiff_data = [imageRep representationUsingType:NSPNGFileType properties:dictionary]; 

NSString *base64 = [tiff_data encodeBase64WithNewlines:NO]; 

Trả lời

4

NSImage là một đối tượng rất trừu tượng. NSImage không thực sự quan tâm cho dù đó là một hình ảnh raster hay một hình ảnh vector; một đối tượng NSImage thậm chí có thể có raster, vector, và thậm chí là lập trình có lập trình cùng một lúc — đó là một cách tổng quát.

Trước khi bạn có thể tạo dữ liệu Base64, bạn phải quyết định những gì bạn muốn mã hóa.

Bước đầu tiên là quyết định xem bạn có muốn mã hóa raster hay vectơ hay không. Trước đây là khá dễ dàng, và tôi đoán nó có thể là những gì bạn có nghĩa là. Tuy nhiên, một NSImage có thể đến từ một nguồn vectơ, chẳng hạn như một tài liệu PDF.

Nếu bạn biết bạn đã tạo hình ảnh từ nguồn raster, bạn chỉ có thể mã hóa dữ liệu nguồn đó.

Nếu đến từ nguồn vectơ, bạn vẫn có thể mã hóa điều đó nếu bạn biết ứng dụng trên đầu giải mã sẽ có thể xử lý nó (ví dụ: nếu đó là ứng dụng Cocoa hoặc Cocoa Touch khác). Mặt khác, nếu ứng dụng trên đầu giải mã có thể không xử lý được dữ liệu vectơ thì bạn nên tránh chiến thuật này.

Một giải pháp hoạt động trong mọi trường hợp là sử dụng NSBitmapImageRep đến create a raster capture của hình ảnh. Khóa tiêu điểm trên hình ảnh, sau đó tạo một NSBitmapImageRep bằng cách sử dụng phương pháp đó, sau đó mở khóa tiêu điểm. Sau đó, sử dụng representationUsingType:properties: để tạo dữ liệu PNG (hoặc bất kỳ định dạng nào phù hợp) cho hình ảnh. Sau đó, Base64 mã hóa dữ liệu PNG (hoặc bất kỳ định dạng nào).

+0

Tôi đoán rằng Alex không muốn base64 mã hóa hình ảnh cho mục đích riêng của mình, nhưng để đáp ứng hợp đồng của một số người nhận, ví dụ một dịch vụ web. Trong trường hợp đó, anh ta sẽ cần phải căn cứ chính xác những gì dịch vụ web mong đợi (có thể là dữ liệu JPG hoặc PNG). Tôi nghi ngờ có nhiều nhu cầu đầu cơ về nhiều cách để mã hóa một hình ảnh, nhưng có lẽ Alex sẽ xác nhận một cách này hay cách khác. – danielpunkass

+0

Hey Guys, tôi nghĩ rằng tôi có mã hóa base64 hoạt động chính xác bằng cách sử dụng mã từ dribin.org nhưng trong khi wordpress chấp nhận và tạo tệp, nó không phải là hình ảnh. http://alexmillsdesign.files.wordpress.com/2009/06/quickicon5.jpg Tôi tin rằng tôi không nhận được dữ liệu phù hợp từ đối tượng NSImage vì vậy tôi đã thay đổi mã của mình trong phần chỉnh sửa câu hỏi ban đầu của tôi. Tôi mới lập trình hình ảnh, tôi đang đi sai ở đâu? –

+0

1. Sử dụng hằng số có tên (NSImageCompressionFactor, không phải @ "NSImageCompressionFactor"). 2. Sử dụng một thể hiện NSNumber, không phải là một chuỗi có chứa một biểu diễn thập phân. 3. Không phải là nó quan trọng, bởi vì PNG không hỗ trợ NSImageCompressionFactor anyway. 4. Bạn đang tạo và tải lên dữ liệu PNG, chứ không phải JPEG. Hoặc sử dụng .png làm đuôi tệp, hoặc tạo và tải lên dữ liệu JPEG chứ không phải PNG. 5. Nếu bạn tải xuống, bạn sẽ thấy rằng đó là dữ liệu base64. Có lẽ bạn không thực sự cần phải mã hóa base64? –

2

Apple không cung cấp bất kỳ sự giúp đỡ đặc biệt ở đây, vì vậy bạn có để giải quyết sự phức tạp riêng, một cách của bạn này hay cách khác.

May mắn thay, có một số tài nguyên có sẵn để giúp việc này trở nên dễ dàng hơn. Cách tiếp cận đầu tiên là tự làm mã hóa và giải mã. Google Toolbox for Mac có một ví dụ điển hình của phương pháp này và bạn có thể có thể chỉ cần sử dụng file nguồn này như-là:

http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMBase64.m

Nếu bạn chỉ xây dựng cho Mac, nơi mà các thư viện OpenSSH là có sẵn, sau đó bạn có thể tận dụng lợi thế của một số chức năng trong các thư viện để thực hiện mã hóa và giải mã:

http://www.dribin.org/dave/blog/archives/2006/03/12/base64_cocoa/

2

tôi đã có một loạt các mã, trong đó có Base64 phân tích cú pháp dựa trên việc thực hiện trong OmniFoundation, trong my toolkit on github . Đặc biệt, hãy xem Extensions/NSData + Base64.h.

1

Đây là một phần mở rộng Swift 2 để chuyển đổi NSImage thành một chuỗi base64:

private extension NSImage { 
    var base64String:String? { 
    guard let rep = NSBitmapImageRep(
     bitmapDataPlanes: nil, 
     pixelsWide: Int(size.width), 
     pixelsHigh: Int(size.height), 
     bitsPerSample: 8, 
     samplesPerPixel: 4, 
     hasAlpha: true, 
     isPlanar: false, 
     colorSpaceName: NSDeviceRGBColorSpace, 
     bytesPerRow: 0, 
     bitsPerPixel: 0 
     ) else { 
      print("Couldn't create bitmap representation") 
      return nil 
    } 

    NSGraphicsContext.saveGraphicsState() 
    NSGraphicsContext.setCurrentContext(NSGraphicsContext(bitmapImageRep: rep)) 
    drawAtPoint(NSZeroPoint, fromRect: NSZeroRect, operation: .CompositeSourceOver, fraction: 1.0) 
    NSGraphicsContext.restoreGraphicsState() 

    guard let data = rep.representationUsingType(NSBitmapImageFileType.NSPNGFileType, properties: [NSImageCompressionFactor: 1.0]) else { 
     print("Couldn't create PNG") 
     return nil 
    } 
    return data.base64EncodedStringWithOptions([]) 
} 
} 
1

Swift 3

extension NSImage { 
    var base64String:String? { 
     guard let rep = NSBitmapImageRep(
      bitmapDataPlanes: nil, 
      pixelsWide: Int(size.width), 
      pixelsHigh: Int(size.height), 
      bitsPerSample: 8, 
      samplesPerPixel: 4, 
      hasAlpha: true, 
      isPlanar: false, 
      colorSpaceName: NSDeviceRGBColorSpace, 
      bytesPerRow: 0, 
      bitsPerPixel: 0 
      ) else { 
       print("Couldn't create bitmap representation") 
       return nil 
     } 

     NSGraphicsContext.saveGraphicsState() 
     NSGraphicsContext.setCurrent(NSGraphicsContext(bitmapImageRep: rep)) 
     draw(at: NSZeroPoint, from: NSZeroRect, operation: .sourceOver, fraction: 1.0) 
     NSGraphicsContext.restoreGraphicsState() 

     guard let data = rep.representation(using: NSBitmapImageFileType.PNG, properties: [NSImageCompressionFactor: 1.0]) else { 
      print("Couldn't create PNG") 
      return nil 
     } 

     return data.base64EncodedString(options: []) 
    } 
}