1 / 30

Pixel Test

Pixel Test. 朱中華 2010/11/25. CreateARGBBitmapContext. CGContextRef CreateARGBBitmapContext (CGImageRef inImage, CGSize size) { CGContextRef context = NULL; CGColorSpaceRef colorSpace; void * bitmapData; int bitmapByteCount; int bitmapBytesPerRow;

Download Presentation

Pixel Test

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Pixel Test 朱中華 2010/11/25

  2. CreateARGBBitmapContext • CGContextRef CreateARGBBitmapContext (CGImageRef inImage, CGSize size) • { • CGContextRef context = NULL; • CGColorSpaceRef colorSpace; • void * bitmapData; • int bitmapByteCount; • int bitmapBytesPerRow; • size_t pixelsWide = size.width; • size_t pixelsHigh = size.height; • bitmapBytesPerRow = (pixelsWide * 4); • bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); • colorSpace = CGColorSpaceCreateDeviceRGB(); • if (colorSpace == NULL) • { • fprintf(stderr, "Error allocating color space\n"); • return NULL; • }

  3. CreateARGBBitmapContext (Cont.) • // allocate the bitmap & create context • bitmapData = malloc( bitmapByteCount ); • if (bitmapData == NULL) • { • fprintf (stderr, "Memory not allocated!"); • CGColorSpaceRelease( colorSpace ); • return NULL; • } • context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, • bitmapBytesPerRow, colorSpace, • kCGImageAlphaPremultipliedFirst); • if (context == NULL) • { • free (bitmapData); • fprintf (stderr, "Context not created!"); • } • CGColorSpaceRelease( colorSpace ); • return context; • }

  4. RequestImagePixelData • // Return a C-based bitmap of the image data inside an image • unsigned char *RequestImagePixelData(UIImage *inImage) • { • CGImageRef img = [inImage CGImage]; • CGSize size = [inImage size]; • CGContextRef cgctx = CreateARGBBitmapContext(img, size); • if (cgctx == NULL) return NULL; • CGRect rect = {{0,0},{size.width, size.height}}; • CGContextDrawImage(cgctx, rect, img); • unsigned char *data = CGBitmapContextGetData (cgctx); • CGContextRelease(cgctx); • return data; • }

  5. rossHairView • @interface CrossHairView : UIView • @end • @implementation CrossHairView • - (void) drawRect: (CGRect) aRect • { • // Create a new path • CGContextRef context = UIGraphicsGetCurrentContext(); • CGMutablePathRef path = CGPathCreateMutable(); • // Set up the stroke characteristics • CGContextSetLineWidth(context, 3.0f); • CGFloat gray[4] = {0.75f, 0.75f, 0.75f, 1.0f}; • CGContextSetStrokeColor(context, gray);

  6. rossHairView (Cont.) • // Add circle to path • CGRect limits = CGRectMake(2.0f, 2.0f, SIDELENGTH - 4.0f, SIDELENGTH - 4.0f); • CGPathAddEllipseInRect(path, NULL, limits); • CGContextAddPath(context, path); • // Add cross to path, leaving an inspection point in the middle • CGContextMoveToPoint(context, 0.0f, SIDELENGTH/2.0f); • CGContextAddLineToPoint(context, (SIDELENGTH/2.0f) - 2.0f, SIDELENGTH/2.0f); • CGContextMoveToPoint(context, (SIDELENGTH /2.0f) + 2.0f, SIDELENGTH/2.0f); • CGContextAddLineToPoint(context, SIDELENGTH, SIDELENGTH/2.0f); • CGContextMoveToPoint(context, SIDELENGTH/2.0f, 0.0f); • CGContextAddLineToPoint(context, SIDELENGTH/2.0f, (SIDELENGTH / 2.0f) - 2.0f); • CGContextMoveToPoint(context, SIDELENGTH/2.0f, SIDELENGTH); • CGContextAddLineToPoint(context, SIDELENGTH/2.0f, (SIDELENGTH / 2.0f) + 2.0f); • CGContextStrokePath(context); • CFRelease(path); • } • @end

  7. BitMapView • // Create an Image View that stores a copy of its image as an addressable bitmap • @interface BitMapView : UIImageView • { • unsigned char *bitmap; • CGSize size; • } • @end

  8. initWithFrame • - (id) initWithFrame: (CGRect) aFrame • { • if (!(self = [super initWithFrame: aFrame])) return NULL; • // initialize by adding the cross-hair • CrossHairView *crossHair = [[CrossHairView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, SIDELENGTH, SIDELENGTH)]; • crossHair.tag = CROSSHAIR_TAG; • crossHair.backgroundColor = [UIColor clearColor]; • crossHair.center = CGPointMake(160.0f, 240.0f); • [self addSubview:crossHair]; • [crossHair release]; • return self; • }

  9. pointInside • (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event • { • long startByte = (int)((point.y * size.width) + point.x) * 4; • int alpha = (unsigned char) bitmap[startByte]; • return (alpha > 0.5); • }

  10. touchesMoved • - (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event • { • CGPoint pt = [[touches anyObject] locationInView:self]; • long startByte = (int)((pt.y * size.width) + pt.x) * 4; • // Note these points are slightly off in the simulator • [self viewWithTag:CROSSHAIR_TAG].center = pt; • // Output RGB values. The alpha value has offset 0 • /* printf("[%3d, %3d] %3dR %3dG %3dB\n", (int)pt.x, (int)pt.y, • (unsigned char) bitmap[startByte+1], • (unsigned char) bitmap[startByte+2], • (unsigned char) bitmap[startByte+3]); */ • [self viewWithTag:COLOR_VIEW_TAG].backgroundColor = [UIColor • colorWithRed: (float) (bitmap[startByte+1]/255.0f) • green: (float) (bitmap[startByte+2]/255.0f) • blue: (float) (bitmap[startByte+3]/255.0f) • alpha: 1.0f]; • }

  11. setImage • -(void) setImage:(UIImage *) anImage • { • [super setImage:anImage]; • bitmap = RequestImagePixelData(anImage); • size = [anImage size]; • UIView *colorView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 400.0f, 320.0f, 80.0f)]; • colorView.userInteractionEnabled = NO; • colorView.backgroundColor = [UIColor blueColor]; • colorView.tag = COLOR_VIEW_TAG; • [self addSubview:colorView]; • [colorView release]; • }

  12. HelloController • @interface HelloController : UIViewController • @end • @implementation HelloController • - (void)loadView • { • BitMapView *contentView = [[BitMapView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; • [contentView setImage:[UIImage imageNamed:@"image2.jpg"]]; • [contentView setUserInteractionEnabled:YES]; • self.view = contentView; • [contentView release]; • } • @end

  13. SampleAppDelegate • @interface SampleAppDelegate : NSObject <UIApplicationDelegate> • @end • @implementation SampleAppDelegate • - (void)applicationDidFinishLaunching:(UIApplication *)application { • UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; • HelloController *hello = [[HelloController alloc] init]; • [window addSubview:hello.view]; • [window makeKeyAndVisible]; • [application setStatusBarHidden:YES]; • } • @end

  14. Main • int main(int argc, char *argv[]) • { • NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; • int retVal = UIApplicationMain(argc, argv, nil, @"SampleAppDelegate"); • [pool release]; • return retVal; • }

  15. demo

  16. Overview • 這個程式會在iPhone螢幕上顯示一個image(image在image2.jpg內),並放一個圓形的pixel tester在image之上,一開始,image下方顯示一條藍色bar,一旦移動該pixel tester,中心pixel的顏色會立即顯示在下方bar上,見下圖,任何時候,隨著pixel tester移動,其中心所在位置的顏色會顯示在下方bar。最左邊的圖是剛開始,image下方顯示一條藍色bar,pixel tester在螢幕中間,中間是的圖是pixel tester移至上方,右邊的圖是pixel tester移到魚上,在不同的位置,下方bar顯示出image內某pixel的顏色。pixel tester在程式中是以crossHair class來表示:

  17. applicationsDidFinishLaunching • [window addSubview:hello.view]; 跳入hello所在的HelloController class的loadSubView。

  18. loadView • BitMapView *contentView = [[BitMapView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 這一行呼叫initWithFrame開啟一個BitMapView object -- contentView,在initWithFrame內, • CrossHairView *crossHair = [[CrossHairView alloc] initWithFrame:CGReckMake(0.0f, 0.0f, SIDELENGTH, SIDELENGTH)]; // 將( SIDELENGTH, SIDELENGTH ) 這( 40 x 40 )的pixel tester 加入BitMapView object內 • [contentView setImage:[UIImage imageNamed:@"image2.jpg"]];這一行呼叫contentView所屬的BitMapView class中的setImage。

  19. RequestImagePixelData • 下面這一行是call RequestImagePixelData,把anImage(image2.jpg)放入bitmap這個array內,每個pixel 4個byte。 • bitmap = RequestImagePixelData(anImage); • 下面這一行是call CreateARGBBitmapContext,產生一個CGContextRef,以便準備放下image2.jpg的所有pixel。 • CreateARGBBitmapContext(img, size)

  20. CreateARGBBitmapContext • Color Space就是用來表現顏色的方式,例如RGB、CMYK等。 • CGColorSpaceCreateDeviceRGB • Create一個device dependent RGB device color space,return value為CGColorSpaceRef object。

  21. CGBitmapContextCreate • 在CGBitmapContext reference裡,把bitmap所需的memory、width、height、bytesPerRow...等七個parameter放入type 為CGContextRef 的context,回傳context,這七個parameter是: • void *data:一塊memory,至少bytesPerRow * height。這一塊memory,用c的malloc得到,由這個程式放入context內。 • size_t width:bitmap 的width in pixel。 • size_t height:bitmap 的height in pixel。 • size_t bitsPerComponent:32-bit pixel format的RGB,8 bits per component。 • size_t bytesPerRow:一個row多少bytes。

  22. RequestImagePixelData • 這個程式將inImage這file load進memory,並return pointer points to the memory。 注意,這一塊memory是由CreateARGBBitmapContext的malloc來的。 • CGContextDrawImage ( cgctx, rect, img );將image畫上螢幕。 • unsign char *data = CGBitmapContextGetData (cgctx); 會將cgctx內的bitmap image data傳回,讓data這個pointer指向這塊bitmap image data,也就是CreateARGBBitmapContext的malloc來的memory,並由[UIImage imageNamed:@"image2.jpg"]load image2.jpg進memory。

  23. loadView • BitMapView *contentView = ....,call initWithFrame,將crossHair subView放上。 • [contentView setImage:[UIImage imageNamed:@"image2.jpg"]];:拿contentView的資訊,由[UIImage imageNamed:@"image2.jpg"]load image2.jpg進memory。

  24. BitMapView • pointInside:click pixel tester crossHair時,會跳入,如果alpha值>0.5,則系統會繼續。若alpha值<= 0.5,則系統不會繼續。 • touchesMoved:當click及drag時,且如果alpha值> 0.5則跳入 • [self viewWithTag:COLOR_VIEW_TAG].backgroundColor • 將該位置顏色顯示於下方bar。若alpha值< = 0.5,即使click及drag仍不會跳入。

  25. drawRect • 畫出一個圓,中間一個十字的pixel tester(crossHair class),在loadView執行完後,系統會call drawRect: • 行先產生context及path兩個CGContext需用的object。 • CGContextSetStrokeColor(context, gray); • 設定筆畫(stroke)相關資訊,76行設定筆畫的寬度為3pixel(可試試改為1個pixel或5個pixel),77~78行設定筆畫的顏色及透明度,77行gray[4]有四個值,依次為RGBA, • RGB為1是表示全部0表示沒有,例如: • R=1 G=0 B=0表示全紅。 • A值1表示不透明,0表示全透明。所以若A=0,就完全看不到這個pixel tester。

  26. 畫圓 • 設定的方塊內畫一個圓(畫一個圓),2.0f, 20.f表示內縮2.0,因此size少了4.0,所以SIDELENGTH - 4.0f,從(2.0, 2.0)開始,直徑SIDELENGTH - 4.0f。 • CGRect limits = CGRectMake(2.0f, 2.0f, SIDELENGTH - 4.0f, SIDELENGTH - 4.0f); • CGPathAddEllipseInRect(path, NULL, limits); • CGContextAddPath(context, path);

  27. 畫十字 • CGContextMoveToPoint(context, 0.0f, SIDELENGTH/2.0f); CGContextAddLineToPoint(context, (SIDELENGTH/2.0f) - 2.0f, SIDELENGTH/2.0f); CGContextMoveToPoint(context, (SIDELENGTH /2.0f) + 2.0f, SIDELENGTH/2.0f); CGContextAddLineToPoint(context, SIDELENGTH, SIDELENGTH/2.0f); CGContextMoveToPoint(context, SIDELENGTH/2.0f, 0.0f); CGContextAddLineToPoint(context, SIDELENGTH/2.0f, (SIDELENGTH / 2.0f) - 2.0f); CGContextMoveToPoint(context, SIDELENGTH/2.0f, SIDELENGTH); CGContextAddLineToPoint(context, SIDELENGTH/2.0f, (SIDELENGTH / 2.0f) + 2.0f); CGContextStrokePath(context); CFRelease(path);

  28. 畫中間橫線 • CGContextMoveToPoint:在CGContext內, 指定一點為(0, SIDELENGTH/2.0f) = ( 0, 20 ) • CGContextAddLineToPoint:在CGContext內,從前一點(0, 20)畫一條線到( ( SIDELENGTH/2.0f ) - 2.0f, SIDELENGTH/2.0f ) = (18, 20)。 • CGContextMoveToPoint: 指定一點為( (SIDELENGTH/2.0f) + 2.0f, SIDELENGTH/2.0f )= ( 22 , 20 )。也就是離上面(18, 20)向右四個點,如此中間留了一個4點的空間。 • CGContextAddLineToPoint:在CGContext內,從前一點(22, 20)畫一條線到( ( SIDELENGTH, SIDELENGTH/2.0f ) = (40, 20)。至此,pixel tester crossHair的中間橫線畫好了。

  29. Homework 5 • Show color space in R, G, and B • Hand in: due 2010/12/02, 00:00 • chchu777@gmail.com • 以組別學號姓名為檔名來繳報告

  30. Homework 6 (Cont.)

More Related