12

我有以下问题,只能部分解决。我正在使用 XCode 3.2.5,为 iOS 4+ 开发。

我只是尝试创建一个预定义大小的图像,在其上操作像素,然后在 UIImageView 中显示该图像。我的视图由连接到的简单按钮和名为“buttonClicked”的 IBAction 和一个名为“qrImage”并设置为“IBOutlet”的 UIImageView 组成。我使用以下代码:

头文件:myClassViewController.h

#import <UIKit/UIKit.h>

@interface myClassViewController : UIViewController
{
    IBOutlet UIImageView *qrImage;
}

@property (nonatomic, retain) UIImageView   *qrImage;

- (IBAction) buttonClicked;
- (UIImage*) drawQRImage;

@end

主文件 myClassViewController.m

#import "myClassViewController.h"
#include <math.h>

@implementation myClassViewController
@synthesize qrImage;


-(UIImage*) drawQRImage
{
    // load Image
    //
    UIImage *image              = [UIImage imageNamed:@"blank.png"];    
    CGImageRef imageRef         = image.CGImage;
    NSData *data                = (NSData *) CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
    char *pixels                = (char *)[data bytes];

    unsigned long int startPixel, pixelNr;


    // manipulate the individual pixels
    //
    size_t width                = CGImageGetWidth(imageRef);
    size_t height               = CGImageGetHeight(imageRef);

    //
    // [...] deleted some unimportant code here
    //

    pixelNr = 10;

    int red                 = pixelNr*3;
    int green               = pixelNr*3+1;
    int blue                = pixelNr*3+2;

    // Set Pixel-Color Black
    //
    pixels[red]         = 0;
    pixels[green]           = 0;
    pixels[blue]            = 0;

    //
    // [...] deleted some unimportant code here
    //

    // create a new image from the modified pixel data
    //
    size_t bitsPerComponent     = CGImageGetBitsPerComponent(imageRef);
    size_t bitsPerPixel         = CGImageGetBitsPerPixel(imageRef);
    size_t bytesPerRow          = CGImageGetBytesPerRow(imageRef);

    CGColorSpaceRef colorspace  = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo     = CGImageGetBitmapInfo(imageRef);
    CGDataProviderRef provider  = CGDataProviderCreateWithData(NULL, pixels, [data length], NULL);

    CGImageRef newImageRef      = CGImageCreate (
                                                 width,
                                                 height,
                                                 bitsPerComponent,
                                                 bitsPerPixel,
                                                 bytesPerRow,
                                                 colorspace,
                                                 bitmapInfo,
                                                 provider,
                                                 NULL,
                                                 false,
                                                 kCGRenderingIntentDefault
                                                 );

    // the modified image
    //
    UIImage *newImage           = [UIImage imageWithCGImage:newImageRef];

    // cleanup
    //
    free(pixels);
    //CGImageRelease(imageRef); // DO NOT RELEASE OR ON NEXT RUN NSData GETS EXC_BAD_ACCESS
    CGColorSpaceRelease(colorspace);
    CGDataProviderRelease(provider);
    CGImageRelease(newImageRef);

    QRcode_free(qrCode);
    QRinput_free(input);

    [image release];

    // return created Image
    //
    return newImage;
}


-(IBAction) buttonClicked
{
    UIImage *createdUIImg = [self drawQRImage]; 
    qrImage.image = createdUIImg;
}

我希望代码是完全不言自明的,如果不是这里有一个简短的描述:

A. 在 Button-Click 上,我调用 drawQRImage 方法,它会返回一个 UIImage。B. 在 drawQRImage 我打开一个 PNG 文件,直到现在它的大小为 210x210,只有一个白色背景。没有其他的。然后我操纵它上面的一些像素并“将它们涂成黑色”。当前代码应设置像素 nr。11 黑色。完成后,我返回新创建的图像。C. 然后方法 buttonClicked 将在 UIImageView 中显示此图像。

总而言之其实很简单。它也(几乎)完美地工作。但现在我想进行一些修改,但直到现在才能让它们工作:

  1. 我必须返回的图像并不总是 210x210 像素,所以我必须能够更改大小。加载“空白”PNG文件并操作它的像素是迄今为止我设法开始工作的唯一解决方法。一种更优雅的方法是创建一个具有所需大小的白色 BG 的空白图像,我可以在当前方法中使用它。不幸的是,我还没有找到关于该主题的任何内容。仅在处理现有图像上的像素时。这就是我想出当前解决方法的方式。我已经尝试过从以下链接调整大小的片段:Resizing a UIImage the right way

  2. 按钮可以点击多次,绘制的像素也会发生变化。我现在的问题是,我似乎有内存泄漏,因为我注释掉了这一行

    //CGImageRelease(imageRef);

但是,如果我确实释放了 UIImageRef“imageRef”,再次单击该按钮时会出现 EXC_BAD_ACCESS-Error。所以我知道这意味着我尝试访问一个已经被释放的对象。但是我该如何解决这个问题,我不确定我是否在这里得到了一切。我认为 imageRef 将在方法“drawQRImage”的开头新创建,因此当我再次调用该方法时释放它应该不是问题。但看起来我似乎错了。

感谢您的每一点帮助!

4

3 回答 3

4

以下讨论涉及 CGImage 对象的内存管理: 释放 CGImage (CGImageRef)

至于空白图像问题: 绘图到 CGImageRef

于 2011-08-26T08:53:36.700 回答
3

为什么不用这个简单的技巧?这个对我有用。(鉴于这self.imageViewSymbol是一个UIImageView*

self.imageViewSymbol.image = nil;
self.imageView.frame = CGRect(...as you like...);
UIGraphicsBeginImageContext(self.imageViewSymbol.bounds.size);
[self.imageViewSymbol.image drawInRect:self.imageViewSymbol.bounds];
self.imageViewSymbol.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
于 2012-05-12T16:51:40.427 回答
2

豪宅大小和规模以创建图像

UIGraphicsBeginImageContextWithOptions(*defineSize*, NO, *Scale*);
UIImage *imgClearBG = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
于 2017-03-24T11:12:00.443 回答