รับ NSData พื้นฐานจาก UIImage


104

ฉันสามารถสร้างUIImageจากการNSDataใช้[UIImage imageWithData:]หรือ[UIImage initWithData:]วิธีการ

ฉันสงสัยว่าฉันจะได้รับNSDataคืนจากที่มีอยู่UIImageหรือไม่? บางสิ่งบางอย่างในบรรทัดของNSData *myData = [myImage getData];

คำตอบ:


191
NSData *imageData = UIImageJPEGRepresentation(image, 0.7); // 0.7 is JPG quality

หรือ

NSData *imageData = UIImagePNGRepresentation(image);

ขึ้นอยู่กับว่าคุณต้องการข้อมูลของคุณในรูปแบบ PNG หรือรูปแบบ JPG


84
ฉันไม่รู้ว่าทำไมคำตอบนี้ถึงได้รับการโหวตหลายครั้งและไม่เป็นที่ยอมรับ OP ขอให้ดึงข้อมูลที่ได้รับในตอนแรก การใช้UIImageJPEGRepresentationหรือUIImagePNGRepresentation จะแก้ไขข้อมูลและทำการแปลงกลับ มีวิธีใดบ้างที่จะบรรลุสิ่งที่ขอ?
Patrik

6
คำตอบนี้ไม่ดีเพราะจะทำให้คุณภาพของภาพลดลงหากอยู่ในรูปแบบที่สูญเสียไปแล้ว
1dayitwillmake

@CipherCom ฉันเห็นสิ่งที่คุณพูดเกี่ยวกับการต้องการข้อมูลที่แน่นอนกลับคืนมา อย่างไรก็ตามฉันคิดว่าสำหรับคนส่วนใหญ่ที่เจอคำถามคำตอบนี้จะเหมาะกับความต้องการของพวกเขา ... หากคุณพบคำตอบในการรับข้อมูลต้นฉบับคืนโปรดแบ่งปัน;)
tybro0103

@ 1dayitwillmake แม้กระทั่งตัวแทน PNG? ไม่ใช่สาขาความเชี่ยวชาญของฉัน แต่ฉันคิดว่า PNG ไม่ประสบความสูญเสีย?
tybro0103

@ Bob Spryn สิ่งนี้จะไม่ช่วย คุณสมบัติ CIImage ถูกตั้งค่าก็ต่อเมื่อเริ่มต้นด้วย imageWithCIImage: นอกจากนี้ยังไม่ใช่ข้อมูลที่ใช้โดยตรง แต่เป็นวัตถุแทนรูปภาพอื่น
King-Wizard

22

เมื่อเริ่มต้นUIImageวัตถุด้วยinit(data: originalData)สิ่งนั้นoriginalDataจะถูกแปลงเป็นข้อมูลดิบในรูปแบบภายในบางประเภท ข้อมูลเหล่านี้สามารถเรียกดูได้ในภายหลังด้วย

let rawData = myImage.cgImage?.dataProvider?.data as Data?

อย่างไรก็ตามเนื่องจากเป็นวัตถุดิบก็เป็นไปได้แม้จะมีขนาดใหญ่กว่าเมื่อใช้rawDataUIImagePNGRepresentation


ฉันจะทำสิ่งนี้ได้อย่างไรใน Objective-C
h3dkandi

NSData * rawData = (__bridge NSData *) CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));
ZardozSpeaks

@ZardozSpeaks ตัวแปร obj-c ทำงานได้อย่างสมบูรณ์แบบที่จะรวมเป็นส่วนแก้ไขในคำตอบนี้
Kamil.S

6

คุณสามารถคาดหวังได้ว่า UIImage เป็นวัตถุที่จัดรูปแบบเพื่อการแสดงผลดังนั้นจะไม่ใช้ข้อมูลต้นฉบับ (ซึ่งอาจอยู่ในรูปแบบ PNG หรือ JPEG) แต่มีแนวโน้มที่จะเป็นอาร์เรย์พิกเซลหรือรูปแบบภายในอื่น ๆ ในคำอื่น ๆจะไม่เก็บUIImage(data: foo)foo

  1. หากคุณต้องการใช้ที่อื่นในโปรแกรมของคุณ UIImage ดั้งเดิมจะทำได้ดี (ฉันคิดว่านั่นไม่ใช่กรณีที่นี่)

  2. หากคุณต้องการต่ออนุกรมUIImagePNGRepresentation(...)จะใช้งานได้ แต่จะมีขนาดใหญ่เกินไปหากต้นฉบับเป็น JPEG UIImageJPEGRepresentation(...)มักจะส่งผลให้ข้อมูลมีขนาดใหญ่เกินไปเล็กน้อยและสูญเสียเล็กน้อยหากต้นฉบับของคุณคือ PNG ควรเลือกอย่างใดอย่างหนึ่งโดยพิจารณาจากวิธีแสดงภาพและรูปแบบที่คุณคาดว่าจะได้รับ หากคุณกำลังใช้ PNG และต้องการใช้ PNG คุณควรมีขนาดไฟล์ที่ดีและข้อมูลที่เกือบจะเหมือนกันโดยแยกส่วน PNG พิเศษออกไป

  3. หากคุณต้องการรับสำเนาของข้อมูลต้นฉบับที่ถูกต้อง (อาจจะบันทึกไฟล์หลังจากการย่อขนาดย่อหรือเพื่อ SHA1) คุณจะต้องเก็บรักษาข้อมูลนั้นแยกกัน คุณอาจทำสิ่งต่างๆเช่น:

    var image:UIImage
    var imageData:NSData {
        didSet {
            image = UIImage(data: imageData)
        }
    }

4

เพราะฉันสะดุดกับสิ่งนี้และฉันชอบความรวดเร็ว :)

นี่คือคำแปลที่รวดเร็วของโพสต์ของ Caroiline

var imageData = UIImagePNGRepresentation(image)

หรือ

var imageData = UIImageJPEGRepresentation(image, 0.7) 

คำถามไม่ได้เกี่ยวกับความรวดเร็ว
Cross_

3

สวิฟต์ 4.2

let dataPng = image.pngData() // return image as PNG. May return nil if image has no CGImageRef or invalid bitmap format

let dataJpg = image.jpegData(compressionQuality: 1) // return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)

-2

สิ่งที่มีการเปลี่ยนแปลงตั้งแต่คำตอบดังกล่าวข้างต้นได้รับสำหรับผู้ที่ยังคงมองเพราะพวกเขาแบ่งปันความกังวลของ CipherCom: iOS 5 ได้เพิ่มCIImage คุณสมบัติ


ฉันไม่เห็นวิธีใช้ CIImage เพื่อรับ NSData ที่อยู่เบื้องหลัง ... ฉันขาดอะไรไปหรือเปล่า?
tybro0103

4
สิ่งนี้จะไม่ช่วย คุณสมบัติCIImageจะถูกตั้งค่าก็ต่อเมื่อเริ่มต้นด้วยimageWithCIImage:. นอกจากนี้ยังไม่ใช่ข้อมูลที่ใช้โดยตรง แต่เป็นวัตถุแทนรูปภาพอื่น
Patrik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.