位图(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;
}