问题描述
我在Google上进行了大量搜索,但遵循大量GitHub代码,但未成功.
I have made a lot of search on google, followed a lot of GitHub code, without success.
我需要读取一个jpeg文件,例如DPI = 72,大小= 16000x1096然后,我需要调整其大小,以便保存具有72 DPI,800x548像素的jpeg文件这个,在OSX下,所以我可以使用NSIMAGE而不是UIImage!
I need to read a jpeg file, which have a DPI = 72, and size = 16000x1096 for exampleI need, then, to resize it, in order to save a jpeg file, with 72 DPI, 800x548 pixelsthis, under OSX, so I can use NSIMAGE, not UIImage !
我不在乎是否会失去一些品质!
I don't care if I lose some quality !
最后,在进行som ma-ny尝试后,我将最新的代码放在这里,并需要一些帮助:
finally, after making som ma-ny tries, I put here my latest code, and require some help please :
// get source image, jpeg, 1600x1196, 72 dpi
let sourceImage = NSImage(contentsOfFile: source)
// compute the scale, to have the longest size = 800 pixels. 72 DPI
let width = CGFloat(sourceImage!.size.width)
let height = CGFloat(sourceImage!.size.height)
var scale = CGFloat( 800.0 / width)
if width < height {
scale = 800.0 / height
}
let newSize:NSSize = NSSize(width: Int(width * scale), height: Int(height * scale))
print ("new size : " + String(describing: newSize) )
// create a new image, with the "small" size
let newImage = NSImage(size: NSSize(width: newSize.width, height: newSize.height))
// lockfocus : draw will be done in this image
newImage.lockFocus()
// interpolation = low, because I don't care of quality
NSGraphicsContext.current()?.imageInterpolation = NSImageInterpolation.low
// draw the big image, into the small one
sourceImage!.draw(in: NSMakeRect(0, 0, newSize.width, newSize.height), from: NSMakeRect(0, 0, width, height), operation: NSCompositingOperation.copy, fraction: CGFloat(1.0))
newImage.unlockFocus()
print("newImage size: " + String(describing: newImage.size))
// display : newImage size: 800 x 598
let cgRef = newImage.cgImage(forProposedRect: nil, context: nil, hints: nil)
let newRep = NSBitmapImageRep(cgImage: cgRef!)
newRep.size = newSize
let jfifProperties = NSDictionary(dictionary: [kCGImagePropertyJFIFIsProgressive:kCFBooleanTrue])
let properties = NSDictionary(dictionary: [kCGImageDestinationLossyCompressionQuality:1.0,
kCGImagePropertyJFIFDictionary:jfifProperties,
kCGImagePropertyDPIHeight: 72.0,
kCGImagePropertyDPIWidth:72.0,
kCGImagePropertyPixelHeight: 1.0,
kCGImagePropertyPixelWidth: 1.0
])
let data = newRep.representation(using: .JPEG, properties: properties as! [String : Any]) //[:])
do {
let url = URL(string: "file://" + destination)
try data?.write(to: url!) //, options: false)
}
catch let error as NSError {
resizeError = error.localizedDescription
return false
}
此代码无法正常工作.我得到一个文件,它是144 DPI和1600 x 1096!
This code does not work properly. I obtain a file, which is 144 DPI, and 1600 x 1096 !
如果我在调试器下打印变量newImage,它将显示以下内容:
if I print, under debugger, the variable newImage, It display this :
newImage的打印说明:\ n \ t< (kCGColorSpaceICCBased; kCGColorSpaceModelRGB;彩色LCD)> \ n \ t \ twidth = 1600,高度= 1196,bpc = 8,bpp = 32,行字节= 6400 \ n \ t \ tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little \ n \ t \ tis掩码?不,有口罩吗?不,有雾面吗?不,应该插值吗?是>"
Printing description of newImage:\n\t< (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Color LCD)>\n\t\twidth = 1600, height = 1196, bpc = 8, bpp = 32, row bytes = 6400 \n\t\tkCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little \n\t\tis mask? No, has mask? No, has matte? No, should interpolate? Yes>"
我们可以看到,内容似乎与原始内容大小相同,不是吗?
as we can see, the content seem to have the same size than the original, isn't it ?
我真的需要一些帮助,我被封锁了,没有找到任何解决办法.
I really need some help, please, I am blocked, and don't find any solution.
感谢您的回答,谁能帮助我.
thanks for any answer, who could help me.
最诚挚的问候奥利维尔
Best regardsOlivier
推荐答案
我自己找到了解决方案,但我感谢人们尝试帮助我.谢谢你.
I found the solution myself, but I appreciate that people tried to help me.thank you to you.
这是我的固定方法:
// get source image, jpeg, 1600x1196, 72 dpi
let sourceImage = NSImage(contentsOfFile: source)
// compute the scale, to have the longest size = 800 pixels. 72 DPI
let width = CGFloat(sourceImage!.size.width)
let height = CGFloat(sourceImage!.size.height)
var scale = CGFloat( resizedLongestSize / width)
if width < height {
scale = resizedLongestSize / height
}
let newSize:NSSize = NSSize(width: Int(width * scale), height: Int(height * scale))
// create NSBitmapRep manually, if using cgImage, the resulting size is wrong
let rep = NSBitmapImageRep(bitmapDataPlanes: nil,
pixelsWide: Int(newSize.width),
pixelsHigh: Int(newSize.height),
bitsPerSample: 8,
samplesPerPixel: 4,
hasAlpha: true,
isPlanar: false,
colorSpaceName: NSDeviceRGBColorSpace,
bytesPerRow: Int(newSize.width * 4),
bitsPerPixel: 32)
let ctx = NSGraphicsContext(bitmapImageRep: rep!)
NSGraphicsContext.saveGraphicsState()
NSGraphicsContext.setCurrent( ctx )
sourceImage!.draw(in: NSMakeRect(0, 0, newSize.width, newSize.height))
ctx?.flushGraphics()
NSGraphicsContext.restoreGraphicsState()
// Get NSData, and save it
let data = rep?.representation(using: .JPEG, properties: [:]) // properties as! [String : Any]) //
do {
let url = URL(string: "file://" + destination)
try data?.write(to: url!) //, options: false)
}
catch let error as NSError {
resizeError = error.localizedDescription
return false
}
此代码效果很好,并在文件中提供了图片,并调整了大小,并提供了一组有限的EXIF数据,如果需要的话,这些数据很容易填充.
this code works well, and provide a picture, in a file, resized, with a limited set of EXIF data, which would be easy to fill if needed.
谢谢奥利维尔
这篇关于如何调整大小-重新采样-更改文件大小-NSImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!