Swift RGB888转RGB565

位图(Bitmap),又称栅格图(英语:Raster graphics)或点阵图,是使用像素阵列(Pixel-array/Dot-matrix点阵)来表示的图像。

根据位深度,可将位图分为1、4、8、16、24及32位图像等。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量越大。例如,位深度为 1 的像素位图只有两个可能的值(黑色和白色),所以又称为二值位图。位深度为 8 的图像有 2^8(即 256)个可能的值。位深度为 8 的灰度模式图像有 256 个可能的灰色值。

RGB图像由三个颜色通道组成。8 位/通道的 RGB 图像中的每个通道有 256 个可能的值,这意味着该图像有 1600 万个以上可能的颜色值。有时将带有 8 位/通道 (bpc) 的 RGB 图像称作 24 位图像(8 位 x 3 通道 = 24 位数据/像素)。通常将使用24位RGB组合数据位表示的的位图称为真彩色位图。

在iOS中,Bitmap的数据由CGContext封装,看下CGContext的初始化方法如下:

init?(data: UnsafeMutableRawPointer?, width: Int, height: Int, bitsPerComponent:Int, bytesPerRow: Int, space: CGColorSpace, bitmapInfo: UInt32)

data: UnsafeMutableRawPointer,用于存放位图的点阵数据

width: Int 位图的宽

height: Int 位图的高

如width=10,height=10,则代表每一行有10个像素,每一列有20个像素

bitsPerComponent:Int 颜色组件或者alpha组件占的bite数,以32位图为列:bitsPerComponent = 8

bytesPerRow: Int 位图每行占的字节数(byte)以32位图为例:一个像素有4byte(rgba)

那么一行字节数: bytesPerRow = 4*width

space: CGColorSpac 颜色空间 CGColorSpaceCreateDeviceRGB

bitmapInfo: UInt32 一个常量,描述这个位图上下文所对应的位图的基本信息,例如:CGImageAlphaInfo.premultipliedLast

接下来我们以两种方式把图片从rgb888转成rgb56

第一种以UInt32来接收位图信息,即一个数据包含了RGBA所有数据


Swift RGB888转RGB565_第1张图片

func rbg565Data() -> Data? {

        guard let cgImage = self.cgImage

            else { return Data() }

        let width = Int(size.width)

        let height = Int(size.height)

        // bytes array

        let srcRowBytes = 4 * width

        var bytes = Array.init(repeating: 0, count: srcRowBytes * height)

        // create context for image

        guard let context = CGContext(data: &bytes, width: width, height: height, bitsPerComponent: 8, bytesPerRow: srcRowBytes, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue )

            else { return nil }

        // fill buffer

        context.interpolationQuality = .high

        context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

        var newBytes = [UInt8]()

        for col in 0..

            for row in 0..

//                let pixeIndex = (col*width+row)*4

                let color = bytes[(col*width+row)]

                let r = UInt8(( color >> 0 ) & 0xff )

                let g = UInt8(( color >> 8 ) & 0xff )

                let b = UInt8(( color >> 16) & 0xff )

                let data = (r & 0xf8) | ((g >> 5) & 0x7)

                newBytes.append(data)

                let data2 = ((g<<3) & 0xE0) | ((b >> 3) & 0x1F)

                newBytes.append(data2)

            }

        }


        return Data(bytes: newBytes, count: newBytes.count)


    }

第二种已UInt8来存储位图信息,即一个数据只包含RGBA中一个通道信息,比如R


Swift RGB888转RGB565_第2张图片

func rbg565Data() -> Data? {

        guard let cgImage = self.cgImage

            else { return Data() }

        let width = Int(size.width)

        let height = Int(size.height)

        // bytes array

        let srcRowBytes = 4 * width

        var bytes = Array.init(repeating: 0, count: srcRowBytes * height)

        // create context for image

        guard let context = CGContext(data: &bytes, width: width, height: height, bitsPerComponent: 8, bytesPerRow: srcRowBytes, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue )

            else { return nil }


        // fill buffer

        context.interpolationQuality = .high

        context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

        var newBytes = [UInt8]()

        for i in 0..<(bytes.count/4) {

            let pixeIndex = i*4

            let r = UInt8(bytes[pixeIndex])

            let g = UInt8(bytes[pixeIndex+1])

            let b = UInt8(bytes[pixeIndex+2])

            let data:UInt8 = (r & 0xf8) | ((g >> 5) & 0x7)

            newBytes.append(data)

            let data2:UInt8 = ((g<<3) & 0xE0) | ((b >> 3) & 0x1F)

            newBytes.append(data2)

//            logD("---r=\(r),g=\(g),b=\(b),data=\(data),data1=\(data2)")

        }

        return Data(bytes: newBytes, count: newBytes.count)


    }

你可能感兴趣的:(Swift RGB888转RGB565)