如何从强度值重建灰度图像? [英] How to reconstruct grayscale image from intensity values?

查看:90
本文介绍了如何从强度值重建灰度图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常需要从图像获取像素数据或从像素数据重建该图像.如何拍摄图像,将其转换为像素值数组,然后使用 CoreGraphics Swift 中使用像素数组进行重建?

It is commonly required to get the pixel data from an image or reconstruct that image from pixel data. How can I take an image, convert it to an array of pixel values and then reconstruct it using the pixel array in Swift using CoreGraphics?

这个问题的答案质量遍地都是,所以我想要一个规范的答案.

The quality of the answers to this question have been all over the place so I'd like a canonical answer.

推荐答案

获取像素值作为数组

此功能可以轻松扩展到彩色图像.为简单起见,我使用灰度,但我已评论了更改以获取RGB.

Get pixel values as an array

This function can easily be extended to a color image. For simplicity I'm using grayscale, but I have commented the changes to get RGB.

func pixelValuesFromImage(imageRef: CGImage?) -> (pixelValues: [UInt8]?, width: Int, height: Int)
{
    var width = 0
    var height = 0
    var pixelValues: [UInt8]?
    if let imageRef = imageRef {
        let totalBytes = imageRef.width * imageRef.height
        let colorSpace = CGColorSpaceCreateDeviceGray()
        
        pixelValues = [UInt8](repeating: 0, count: totalBytes)
        pixelValues?.withUnsafeMutableBytes({
            width = imageRef.width
            height = imageRef.height
            let contextRef = CGContext(data: $0.baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: width, space: colorSpace, bitmapInfo: 0)
            let drawRect = CGRect(x: 0.0, y:0.0, width: CGFloat(width), height: CGFloat(height))
            contextRef?.draw(imageRef, in: drawRect)
        })
    }

    return (pixelValues, width, height)
}

从像素值获取图像

我将图像(在本例中为每像素灰度8位)重建为 CGImage .

func imageFromPixelValues(pixelValues: [UInt8]?, width: Int, height: Int) ->  CGImage?
{
    var imageRef: CGImage?
    if let pixelValues = pixelValues {
        let bitsPerComponent = 8
        let bytesPerPixel = 1
        let bitsPerPixel = bytesPerPixel * bitsPerComponent
        let bytesPerRow = bytesPerPixel * width
        let totalBytes = width * height
        let unusedCallback: CGDataProviderReleaseDataCallback = { optionalPointer, pointer, valueInt in }
        let providerRef = CGDataProvider(dataInfo: nil, data: pixelValues, size: totalBytes, releaseData: unusedCallback)

        let bitmapInfo: CGBitmapInfo = [CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue), CGBitmapInfo(rawValue: CGImageByteOrderInfo.orderDefault.rawValue)]
        imageRef = CGImage(width: width,
                           height: height,
                           bitsPerComponent: bitsPerComponent,
                           bitsPerPixel: bitsPerPixel,
                           bytesPerRow: bytesPerRow,
                           space: CGColorSpaceCreateDeviceGray(),
                           bitmapInfo: bitmapInfo,
                           provider: providerRef!,
                           decode: nil,
                           shouldInterpolate: false,
                           intent: .defaultIntent)
    }

    return imageRef
}
    

在运动场中删除代码

您需要将图像复制到Playground的Resources文件夹中,然后更改下面的文件名和扩展名以进行匹配.最后一行的结果是从CGImage构造的UIImage.

Demoing the code in a Playground

You'll need an image copied into the Playground's Resources folder and then change the filename and extension below to match. The result on the last line is a UIImage constructed from the CGImage.

import Foundation
import CoreGraphics
import UIKit
import PlaygroundSupport

let URL = playgroundSharedDataDirectory.appendingPathComponent("zebra.jpg")
print("URL \(URL)")

var image: UIImage? = nil
if FileManager().fileExists(atPath: URL.path) {
    do {
        try NSData(contentsOf: URL, options: .mappedIfSafe)
    } catch let error as NSError {
        print ("Error: \(error.localizedDescription)")
    }
    image = UIImage(contentsOfFile: URL.path)
} else {
    print("File not found")
}

let (intensityValues, width, height) = pixelValuesFromImage(imageRef: image?.cgImage)
let roundTrippedImage = imageFromPixelValues(pixelValues: intensityValues, width: width, height: height)
let zebra = UIImage(cgImage: roundTrippedImage!)

这篇关于如何从强度值重建灰度图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆