Ho un problema seguente e potrei risolverlo solo parzialmente. Sto lavorando con XCode 3.2.5, in sviluppo per iOS 4+.Come creare UIImage vuoto o vuoto o CGImage e manipolare i pixel su di esso (Xcode)?
Ho semplicemente provato a creare un'immagine di dimensioni predefinite, manipolare i pixel su di esso e quindi mostrare l'immagine in un UIImageView. La mia vista consiste in un semplice pulsante collegato a e IBAction chiamato "buttonClicked" e un UIImageView chiamato "qrImage" e impostato come "IBOutlet". Io uso seguente codice:
Header-File: myClassViewController.h
#import <UIKit/UIKit.h>
@interface myClassViewController : UIViewController
{
IBOutlet UIImageView *qrImage;
}
@property (nonatomic, retain) UIImageView *qrImage;
- (IBAction) buttonClicked;
- (UIImage*) drawQRImage;
@end
Main-File 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;
}
Spero che il codice è piuttosto auto esplicativo, se non qui una breve Descrizione:
A. Con pulsante Fare clic sul metodo drawQRImage, che restituirà un UIImage. B. Inside drawQRImage Apro un file PNG, fino ad ora ha la dimensione 210x210 e solo uno sfondo bianco. Nient'altro. Quindi manipolo alcuni dei pixel su di esso e "li dipingo di nero". Il codice corrente dovrebbe impostare pixel nr. 11 nero. Al termine, restituisco l'immagine appena creata. C. Il metodo buttonClicked mostrerà questa immagine all'interno di UIImageView.
Tutto sommato in realtà molto semplice. Funziona anche (quasi) perfettamente. Ma ora voglio fare alcune modifiche, ma non riesco a farli lavorare fino ad ora:
L'immagine che ho di tornare non è sempre 210x210 pixel, quindi devo essere in grado di modificare le dimensioni. Il caricamento di un file PNG "vuoto" e la manipolazione dei suoi pixel è stata l'unica soluzione fino a quando sono riuscito a lavorare. Un modo più elegante sarebbe creare un'immagine vuota con BG bianca della dimensione desiderata che potrei usare nel mio metodo attuale. Sfortunatamente non ho ancora trovato nulla sull'argomento. Solo manipolando i pixel su tutte le immagini già esistenti. È così che mi è venuta l'attuale soluzione alternativa. Ho già provato il ridimensionamento per il ridimensionamento dal seguente Link: Resizing a UIImage the right way
Il pulsante può essere selezionato più volte, anche i pixel dipinti cambieranno. Il mio problema ora è che mi sembra di avere una perdita di memoria perché ho commentato la linea
// CGImageRelease (imageRef);
Ma se faccio rilasciare l'UIImageRef "imageRef", mi metterò un EXC_BAD_ACCESS-errore quando si fa clic di nuovo il pulsante. Quindi so che questo significa che provo ad accedere a un oggetto che è già stato rilasciato. Ma come posso risolvere questo problema, non sono sicuro di avere tutto qui. Ho pensato che imageRef verrà creato di nuovo all'inizio del metodo "drawQRImage" e quindi rilasciandolo non dovrebbe essere un problema quando chiamo il metodo un'altra volta. Ma sembra che sembri sbagliato.
Ogni piccolo aiuto è apprezzato!
ho trovato un non perfetto ma soluzione più o meno accettabile per il problema # 1. Pubblicherò il codice non appena l'avrò testato e finito. Tuttavia, sarei felice se qualcuno potesse darmi un consiglio su come creare un'immagine vuota invece di dover aprire un png bianco/bianco (come faccio adesso). Riguardo al problema n. 2: Credo che i seguenti link rispondano alla mia domanda con il mio errore EXC_BAD_ACCESS, giusto? http://stackoverflow.com/questions/1428102/does-cgimagerelease-free-uiimages-memory – EliteTUM