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所有数据


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<UInt32>.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..<height {

            for row in 0..<width {

//                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


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<UInt8>.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)


    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335