如何使用DPI设置创建UIImage?

时间:2016-02-17 15:32:10

标签: ios swift uiimage core-graphics

我有一个UIImage,我希望将它保存到具有DPI元数据集的照片中。我知道UIImage是不可变的,所以我必须创建一个新的UIImage。我使用this answer作为参考,在UIImage上创建一个swift扩展函数,生成一个带有DPI集的新UIImage。我已成功将其保存到UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)的照片中。我通过电子邮件发送给自己(设置为'实际尺寸')并在预览中打开它,但DPI​​始终保持在72.

这是我转换的函数:

func imageWithDPI(dpi :Int) -> UIImage? {
    guard let sourceImageData = UIImageJPEGRepresentation(self, 0.8) else {
        print("Couldn't make PNG Respresentation of UIImage")
        return nil
    }

    guard let source = CGImageSourceCreateWithData(sourceImageData, nil) else {
        print("Couldn't create source with sourceImageData")
        return nil
    }

    var metadata = CGImageSourceCopyPropertiesAtIndex(source, 0, nil) as? [String:AnyObject] ?? [String:AnyObject]()
    metadata[kCGImagePropertyDPIWidth as String] = dpi
    metadata[kCGImagePropertyDPIHeight as String] = dpi

    var exifDictionary = metadata[kCGImagePropertyTIFFDictionary as String] as? [String:AnyObject] ?? [String:AnyObject]()
    exifDictionary[kCGImagePropertyTIFFXResolution as String] = dpi
    exifDictionary[kCGImagePropertyTIFFYResolution as String] = dpi
    metadata[kCGImagePropertyTIFFDictionary as String] = exifDictionary

    var jfifDictionary = metadata[kCGImagePropertyJFIFDictionary as String] as? [String:AnyObject] ?? [String:AnyObject]()
    jfifDictionary[kCGImagePropertyJFIFXDensity as String] = dpi
    jfifDictionary[kCGImagePropertyJFIFYDensity as String] = dpi
    jfifDictionary[kCGImagePropertyJFIFVersion as String] = 1
    metadata[kCGImagePropertyJFIFDictionary as String] = jfifDictionary

    guard let uti = CGImageSourceGetType(source) else {
        print("Couldn't get type from source")
        return nil
    }

    let destinationImageData = NSMutableData()
    guard let destination = CGImageDestinationCreateWithData(destinationImageData, uti, 1, nil) else {
        print("Couldn't create destination with destinationImageData")
        return nil
    }

    CGImageDestinationAddImageFromSource(destination, source,0, metadata)
    CGImageDestinationFinalize(destination)

    return UIImage(data: destinationImageData)
}

我在核心图形学方面有点深入,所以任何建议都会非常感激。

非常感谢提前。

1 个答案:

答案 0 :(得分:1)

当您从#include <iostream> #include <string> int delay; long long int counter1 = 0; // Add LL beyond 9 digits long long int endcount = 0; // while loop end counter long long int seed1 = 0; int match2 = 0; int ST = 0; int flag = 0; float progress = 0; int step1 = 0; int step2 = 0; int step3 = 0; int main() { system("color b0"); std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"; std::cout << " Poor Key Finder Version 1.0\n"; std::cout << " Build 01/30/2016\n"; std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n"; std::cout << " Enter Starting Key Value\n"; std::cin >> counter1; std::cout << " Enter Ending Key Value\n"; std::cin >> endcount; std::cout << " Enter Duplicate Character Counter Value\n"; std::cin >> flag; system("cls"); std::string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-+=?<>:\\/~.,;"; std::string str2= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-+=?<>:\\/~.,;"; system("@echo. Started on %date% at %time%>>LogKey.txt"); system("color f0"); std::cout << "Poor Key Finder - Search for " << flag << " or more matches \n"; std::cout << "Searching through Key Values of " << counter1 << " thru "<<endcount<<"\n\ n"; std::cout << " WARNING - Program Running Please Wait...\n\n"; while (counter1 <= endcount) { seed1 = counter1; srand(seed1); random_shuffle(str.begin(), str.end()); // Shuffle the string ST = 0; match2 = 0; progress = ((100 * counter1) / endcount); if (progress == 25) { step1++; if (step1 == 1) { std::cout << "25% Complete\n"; } else { } } else if (progress == 50) { step2++; if (step2 == 1) { std::cout << "50% Complete\n"; } else { } } else if (progress == 75) { step3++; if (step3 == 1) { std::cout << "75% Complete\n"; } else { } } else if (endcount == counter1) { std::cout << "100% Complete\n"; } else { } while (ST <= 85) { if (str[ST] == str2[ST]) { match2++; } else { } ST++; } if (match2 >= flag) { std::cout << "Greater or Equal to = " << flag << " ===== " << seed1 << "\n"; } else { } counter1++; } std::cout << "Completed = " << endcount << "\n\n\n"; system("@echo. Ended on %date% at %time%>>LogKey.txt"); system("pause"); return 0; } 创建时,UIImage可能会剥离图像中的所有元数据,包括DPI。我最近在通过iOS的destinationImageData API共享图片时遇到了这个问题。如果我从UIActivityItemProvider方法返回UIImage *,则所有元数据都会丢失。修复方法是返回- (id)itemNSData *

尝试直接返回NSURL *,或将其保存到文件&amp;通过电子邮件发送给自己。

我很想知道为什么要为图像设置DPI?如今,DPI几乎对所有数字图像都毫无意义(除非图像是为了准确地表示物理对象的尺寸)。实际像素分辨率远比DPI重要。