美文网首页
iOS 获取一张图片(Bitmap)的点阵数据

iOS 获取一张图片(Bitmap)的点阵数据

作者: Hason | 来源:发表于2018-07-19 15:08 被阅读0次

    位图(Bitmap)   位图图像(bitmap), 亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的。

    RGB      位图颜色的一种编码方法,用红、绿、蓝三原色的光学强度来表示一种颜色。这是最常见的位图编码方法,可以直接用于屏幕显示

    CMYK     位图颜色的一种编码方法,用青、品红、黄、黑四种颜料含量来表示一种颜色。常用的位图编码方法之一,可以直接用于彩色印刷。

    Alpha通道    在原有的图片编码方法基础上,增加像素的透明度信息。图形处理中,通常把RGB三种颜色信息称为红通道、绿通道和蓝通道,相应的把透明度称为Alpha通道。多数使用颜色表的位图格式都支持Alpha通道。

    色彩深度    色彩深度又叫色彩位数,即位图中要用多少个二进制位来表示每个点的颜色,是分辨率的一个重要指标。常用有1位(单色),2位(4色,CGA),4位(16色,VGA),8位(256色),16位(增强色),24位(真彩色)和32位等。色深8位及以上的位图还可以根据其中分别表示RGB三原色或CMYK四原色(有的还包括Alpha通道)的位数进一步分类,如16位位图图片还可分为R5G6B5,R5G5B5X1(有1位不携带信息),R5G5B5A1,R4G4B4A4等等。

    BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BblP文件所占用的空间很大。BMP文件的图像深度可选1bit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。

    典型的BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。

    在iOS开发中使用的位图大部分是32位RGBA模式,以下是这种模式的简单图像处理。

    首先我们需要知道什么是32位RGBA模式的位图。32位就表示一个这种模式位图的一个像素所占内存为32位,也就是4个字节的长度。R、G、B、A分别代表red,green,blue和alpha,也就是颜色组成的三原色与透明度值。RGBA每一个占用一个字节的内存。

    代码部分

    1,CGImageRef

    CGImageRef CGImageCreate {

    size_t width,//图片的宽度

    size_t height,//图片的高度

    size_t bitsPerComponent,//图片每个颜色的bits

    size_t bitsPerPixel,//每一个像素占用的buts,15 位24位 32位等等

    size_t  bytesPerRow,//每一行占用多少bytes 注意是bytes不是bits 1byte = 8bit

    CGColorSpaceRef colorspace,//颜色空间,比如rgb

    CGBitmapInfo bitmapInfo,//layout ,像素中bit的布局, 是rgba还是 argb

    CGDataProviderRef provider,//数据源提供者,url或者内存..

    const CGFloat decode[],//一个解码数组

    boo lshouldInterpolate,//抗锯齿参数

    CGColorRenderingIntent intent//图片渲染相关参数

    }

    2, 要得到BMP每个点RGB值,首先要得到每个点的像素数据 ,这里得到的是每个点的R,G,B,A 值组合起来的一个unsigned char *pixels类型的数据,代码如下:

    unsigned char *pixels = calloc(picWidth * picHeight * 4, sizeof(unsigned char)); // 取图片首地址,准备用来存储数据的数组

        size_t bitsPerComponent = 8; // 每个像素元素位数为 8 bit,即 rgba 每位各 1 个字节

        size_t bytesPerRow = picWidth *4; //一个像素 4 个字节,则一行共 4 * width 个字节

        CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); // 创建rgb颜色空间 这决定了输出颜色的编码是 RGB 还是其他(比如 YUV)

        CGContextRef context =

        CGBitmapContextCreate(pixels,

                              picWidth,

                              picHeight,

                              bitsPerComponent,

                              bytesPerRow,

                              space,

                              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

        CGContextDrawImage(context, CGRectMake(0, 0, picWidth, picHeight), image.CGImage);//将图片的数据写入上下文

    //释放

        CGColorSpaceRelease(space);

        CGContextRelease(context);

    3,项目中有几个因素:

    一,数据极性为正极性时r,g,b值不变,为负极性时 r,g,b 值要取反。

    二,因为项目中特技为连续左、右移时,左补点为0,其他特技需要左补点数为 X坐标对8取余。

    三,获取的R,G,B数据拼接起来便是所要的数据,此数据与颜色和所需的红绿顺序有关,比如需要的是单色的,那 么只需要取 R即红的值即可,双色的可以使R+B,也可以是B+R等等......

    代码:

    //文字转图片生成的点阵数据

    - (Byte *) getByteDataWithImage:(UIImage *)image {

        BOOL pol = self.dataPolarIndex == 1;

        NSInteger bit = 0 ;

        NSInteger addLeft = 0;

        NSInteger picWidth = image.size.width,picHeight = image.size.height;

        //  NSLog(@"图片款高---%ld----%ld",picWidth,picHeight);

        NSInteger shiftBit = 0;

        Byte r;

        Byte g;

        Byte b;

        NSMutableData *lastData = [[NSMutableData alloc]init];

        Byte          *lastByte;

        NSInteger x = _subtitleX;

        if (effectsRow2 == 1 || effectsRow2 == 2) {

            addLeft = 0;

        }else{

            addLeft = x % 8;

        }

        unsigned char *pixels = calloc(picWidth * picHeight * 4, sizeof(unsigned char)); // 取图片首地址//准备用来存储数据的数组

        size_t bitsPerComponent = 8; // 每个像素元素位数为 8 bit,即 rgba 每位各 1 个字节

        size_t bytesPerRow = picWidth *4; //一个像素 4 个字节,则一行共 4 * width 个字节

        CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); // 创建rgb颜色空间 这决定了输出颜色的编码是 RGB 还是其他(比如 YUV)

        CGContextRef context =

        CGBitmapContextCreate(pixels,

                              picWidth,

                              picHeight,

                              bitsPerComponent,

                              bytesPerRow,

                              space,

                              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

        CGContextDrawImage(context, CGRectMake(0, 0, picWidth, picHeight), image.CGImage);//将图片的数据写入上下文

        CGColorSpaceRelease(space);

        CGContextRelease(context);

        NSInteger rgbSpace = ((picWidth + addLeft + 7)/8)  * picHeight;

        NSInteger grayLevel = 0;

        if ([[NSUserDefaults standardUserDefaults]integerForKey:@"selectGLRow"]) {

            grayLevel = [[NSUserDefaults standardUserDefaults]integerForKey:@"selectGLRow"];

        }else {

            grayLevel = 1;

        }

        for (NSInteger gray = 1; gray <= grayLevel; gray ++) {

            bit = 7 - (grayLevel - gray);

            unsigned char *rBytes = malloc(rgbSpace);

            unsigned char *gBytes = malloc(rgbSpace);

            unsigned char *bBytes = malloc(rgbSpace);

            NSInteger rgbStep = 0;

            for (NSInteger i = 0; i < picHeight; i ++) {

                r = 0;

                g = 0;

                b = 0;

                shiftBit = 8 - addLeft;

                for (NSInteger j = 0; j < picWidth; j ++) {

                    r |= (((pixels[i*picWidth *4 +j*4 + 0] >> bit)&0x01) << (shiftBit -1));

                    g |= (((pixels[i*picWidth *4 +j*4 + 1] >> bit)&0x01) << (shiftBit -1));

                    b |= (((pixels[i*picWidth *4 +j*4 + 2] >> bit)&0x01) << (shiftBit -1));

                    shiftBit --;

                    if (shiftBit == 0 || (j==picWidth -1)) {

                        if (!pol) {

                            r = ~r;

                            g = ~g;

                            b = ~b;

                        }

                        rBytes[rgbStep] = r;

                        gBytes[rgbStep] = g;

                        bBytes[rgbStep] = b;

                        rgbStep++;

                        shiftBit = 8;

                        r = 0;

                        g = 0;

                        b = 0;

                    }

                }

            }

            switch (self.colorIndex) {

                case 0:

                    [lastData appendBytes:rBytes length:rgbSpace];

                    break;

                case 1:

                    switch (self.RGBOrder) {

                        case 0:

                            [lastData appendBytes:rBytes length:rgbSpace];

                            [lastData appendBytes:gBytes length:rgbSpace];

                            break;

                        case 1:

                            [lastData appendBytes:gBytes length:rgbSpace];

                            [lastData appendBytes:rBytes length:rgbSpace];

                            break;

                        default:

                            [lastData appendBytes:rBytes length:rgbSpace];

                            [lastData appendBytes:gBytes length:rgbSpace];

                            break;

                    }

                    break;

                case 2:

                    switch (self.RGBOrder) {

                        case 2:

                            [lastData appendBytes:rBytes length:rgbSpace];

                            [lastData appendBytes:gBytes length:rgbSpace];

                            [lastData appendBytes:bBytes length:rgbSpace];

                            break;

                        case 3:

                            [lastData appendBytes:rBytes length:rgbSpace];

                            [lastData appendBytes:bBytes length:rgbSpace];

                            [lastData appendBytes:gBytes length:rgbSpace];

                            break;

                        case 4:

                            [lastData appendBytes:gBytes length:rgbSpace];

                            [lastData appendBytes:rBytes length:rgbSpace];

                            [lastData appendBytes:bBytes length:rgbSpace];

                            break;

                        case 5:

                            [lastData appendBytes:gBytes length:rgbSpace];

                            [lastData appendBytes:bBytes length:rgbSpace];

                            [lastData appendBytes:rBytes length:rgbSpace];

                            break;

                        case 6:

                            [lastData appendBytes:bBytes length:rgbSpace];

                            [lastData appendBytes:rBytes length:rgbSpace];

                            [lastData appendBytes:gBytes length:rgbSpace];

                            break;

                        case 7:

                            [lastData appendBytes:bBytes length:rgbSpace];

                            [lastData appendBytes:gBytes length:rgbSpace];

                            [lastData appendBytes:rBytes length:rgbSpace];

                            break;

                        default:

                            [lastData appendBytes:rBytes length:rgbSpace];

                            [lastData appendBytes:gBytes length:rgbSpace];

                            [lastData appendBytes:bBytes length:rgbSpace];

                            break;

                    }

                    break;

                default:

                    [lastData appendBytes:rBytes length:rgbSpace];

                    break;

            }

            free(rBytes);

            free(gBytes);

            free(bBytes);

            rBytes = NULL;

            bBytes = NULL;

            bBytes = NULL;

        }

        free(pixels);

        pixels = NULL;

        [[NSUserDefaults  standardUserDefaults] setInteger:lastData.length forKey:@"subTitleDataLength"];

        [[NSUserDefaults standardUserDefaults] synchronize];

        lastByte = (Byte *)[lastData bytes];

        return lastByte;

    }

    相关文章

      网友评论

          本文标题:iOS 获取一张图片(Bitmap)的点阵数据

          本文链接:https://www.haomeiwen.com/subject/pwltmftx.html