首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用bitmapData修改镜像

使用bitmapData修改镜像
EN

Stack Overflow用户
提问于 2021-03-14 00:29:50
回答 2查看 40关注 0票数 0

所以我有一个方法,可以成功地获取像素的颜色。

代码语言:javascript
复制
//arrColT is an NSMutableArray<NSColor *>
        NSInteger width = [bitIn pixelsWide];
        NSInteger height = [bitIn pixelsHigh];
        NSInteger rowBytes = [bitIn bytesPerRow];
        unsigned char* pixels = [bitIn bitmapData];
        int row, col;
        //For every row,
        for (row = 0; row < height; row++)
        {
            unsigned char* rowStart = (unsigned char*)(pixels + (row * rowBytes));
            unsigned char* nextChannel = rowStart;
            //For every pixel in a row,
            for (col = 0; col < width; col++)
            {
                //Get its color.
                unsigned char red, green, blue, alpha;
                red = *nextChannel;
                int intRed = (int)red;
                nextChannel++;
                green = *nextChannel;
                int intGreen = (int)green;
                nextChannel++;
                blue = *nextChannel;
                int intBlue = (int)blue;
                nextChannel++;
                alpha = *nextChannel;
                int intAlpha = (int)alpha;
                nextChannel++;
                NSColor *colHas = [NSColor colorWithCalibratedRed:(float)intRed/255 green: (float)intGreen/255 blue: (float)intBlue/255 alpha:(float)intAlpha/255];
                for (int i = 0; i<[arrColT count]; i++) {
                    //If the target color is equal to the current color, replace it with the parallel replace color...somehow.
                    if([colHas isEqualTo:arrColT[i]]){
                    }
                }
            }
        }

问题是,如何将颜色数据返回到bitmapData中?

带着希望,

radzo73

EN

回答 2

Stack Overflow用户

发布于 2021-03-14 09:55:10

请参阅Technical Q&A QA1509,它基本上建议

  1. 创建像素缓冲区(通过创建预定义格式的CGContextRef并根据需要绘制图像以在该像素缓冲区中创建字节;
  2. 使用CGBitmapContextCreateImage.

创建结果图像

例如。

代码语言:javascript
复制
- (UIImage *)convertImage:(UIImage *)image
{
    // get image

    CGImageRef imageRef = image.CGImage;

    // prepare context

    CGBitmapInfo    bitmapInfo       = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; // bytes in RGBA order
    NSInteger       width            = CGImageGetWidth(imageRef);
    NSInteger       height           = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorspace       = CGColorSpaceCreateDeviceRGB();

    CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 4 * width, colorspace, bitmapInfo);

    // draw image to that context

    CGRect rect = CGRectMake(0, 0, width, height);
    CGContextDrawImage(context, rect, imageRef);
    uint8_t *buffer = CGBitmapContextGetData(context);

    // ... manipulate pixel buffer bytes here ...

    // get image from buffer

    CGImageRef outputImage = CGBitmapContextCreateImage(context);
    UIImage *result = [UIImage imageWithCGImage:outputImage scale:image.scale orientation:image.imageOrientation];

    // clean up

    CGImageRelease(outputImage);
    CGContextRelease(context);
    CGColorSpaceRelease(colorspace);

    return result;
}

例如,下面是一个黑白转换例程:

代码语言:javascript
复制
/** Convert the image to B&W as a single (non-parallel) task.
 *
 * This assumes the pixel buffer is in RGBA, 8 bits per pixel format.
 *
 * @param buffer The  pixel buffer.
 * @param width        The image width in pixels.
 * @param height       The image height in pixels.
 */
- (void)convertToBWSimpleInBuffer:(uint8_t *)buffer width:(NSInteger)width height:(NSInteger)height
{
    for (NSInteger row = 0; row < height; row++) {
        for (NSInteger col = 0; col < width; col++) {
            NSUInteger offset = (col + row * width) * 4;
            uint8_t *pixel = buffer + offset;

            // get the channels

            uint8_t red   = pixel[0];
            uint8_t green = pixel[1];
            uint8_t blue  = pixel[2];
            uint8_t alpha = pixel[3];

            // update the channels with result

            uint8_t gray = 0.2126 * red + 0.7152 * green + 0.0722 * blue;

            pixel[0] = gray;
            pixel[1] = gray;
            pixel[2] = gray;
            pixel[3] = alpha;
        }
    }
}

如果想要提高性能,可以并行使用dispatch_apply和stride遍历图像缓冲区:

代码语言:javascript
复制
/** Convert the image to B&W, using GCD to split the conversion into several concurrent GCD tasks.
 *
 * This assumes the pixel buffer is in RGBA, 8 bits per pixel format.
 *
 * @param buffer The  pixel buffer.
 * @param width        The image width in pixels.
 * @param height       The image height in pixels.
 * @param count        How many GCD tasks should the conversion be split into.
 */
- (void)convertToBWConcurrentInBuffer:(uint8_t *)buffer width:(NSInteger)width height:(NSInteger)height count:(NSInteger)count
{
    dispatch_queue_t queue = dispatch_queue_create("com.domain.app", DISPATCH_QUEUE_CONCURRENT);
    NSInteger stride = height / count;

    dispatch_apply(height / stride, queue, ^(size_t idx) {
        size_t j = idx * stride;
        size_t j_stop = MIN(j + stride, height);

        for (NSInteger row = j; row < j_stop; row++) {
            for (NSInteger col = 0; col < width; col++) {
                NSUInteger offset = (col + row * width) * 4;
                uint8_t *pixel = buffer + offset;

                // get the channels

                uint8_t red   = pixel[0];
                uint8_t green = pixel[1];
                uint8_t blue  = pixel[2];
                uint8_t alpha = pixel[3];

                // update the channels with result

                uint8_t gray = 0.2126 * red + 0.7152 * green + 0.0722 * blue;

                pixel[0] = gray;
                pixel[1] = gray;
                pixel[2] = gray;
                pixel[3] = alpha;
            }
        }
    });
}
票数 0
EN

Stack Overflow用户

发布于 2021-03-14 10:02:04

这取决于bitIn是什么,但像这样的东西应该能起到作用。

首先,创建一个上下文。如果您要对数据进行大量更改并需要大量图片,您可以执行此操作一次,并保留上下文。

代码语言:javascript
复制
self.ctx = CGBitmapContextCreate ( 
    [bitIn bitmapData],
    [bitIn pixelsWide],
    [bitIn pixelsHigh],
    [bitIn bitsPerPixel],
    [bitIn bytesPerRow],
    [bitIn colorSpace],
    [bitIn bitmapInfo] );

在这里,我自由地使用了bitIn,希望它能提供所有缺失的部分。然后,即使对数据进行了进一步更改,也可以在以后将其组合在一起,使用如下代码

代码语言:javascript
复制
CGImageRef cgImg = CGBitmapContextCreateImage ( self.ctx );
UIImage * img = [UIImage imageWithCGImage:cgImg];
CGImageRelease ( cgImg );

现在,您可以对数据进行更多更改,并执行相同的操作以获得新图像。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66615908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档