zoukankan      html  css  js  c++  java
  • iOS_24_画画板(含取色板)

    终于效果例如以下:



    一、简单说明
     1、使用一个数组 strokesArr(笔画数组)记录全部笔画。数组中保存的是一个个的笔画字典,一个字典就是一个笔画。笔画字典中有三项:笔画的大小、颜色、pointsArrInOneStroke数组,(保存的是touch  begin时的落笔点和touch move过程中经过的点)
     
     2、绘制的时候,从strokesArr(笔画数组)里取出每个字典(一个字典就是一个笔画)。依据字典中笔画的大小、颜色、笔画所经过的点坐标(pointsArrInOneStroke数组)。使用UIBezierPath类完毕笔画绘制
     
     二、撤销和回撤
     一个笔画就是一个字典。 
     撤销:
     使用abandonedStrokesArr (被丢弃的笔画数组)保存要撤销的笔画,即全部笔画数组中的最后一划,
     同一时候将 strokesArr 笔画数组中的最后一个元素删除。
     反之,重做:
     即将abandonedStrokesArr (被丢弃的笔画数组)中最后一个元素加入到全部笔画数组中,同一时候将(被丢弃的笔画数组)中的最后一个元素删除。


    Main.storyboard





    主控制器



    Canvas类封装了画画的全部核心代码


    方法列表


    //
    //  Canvas.h
    //  24_Canvas画画板
    //
    //  Created by beyond on 14-8-26.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    /*
     一、简单说明
     1、使用一个数组 strokesArr(笔画数组)记录全部笔画。数组中保存的是一个个的笔画字典,一个字典就是一个笔画,笔画字典中有三项:笔画的大小、颜色、pointsArrInOneStroke数组。(保存的是touch  begin时的落笔点和touch move过程中经过的点)
     
     2、绘制的时候,从strokesArr(笔画数组)里取出每个字典(一个字典就是一个笔画)。依据字典中笔画的大小、颜色、笔画所经过的点坐标(pointsArrInOneStroke数组)。使用UIBezierPath类完毕笔画绘制
     
     二、撤销和回撤
     一个笔画就是一个字典。

    撤销: 使用abandonedStrokesArr (被丢弃的笔画数组)保存要撤销的笔画。即全部笔画数组中的最后一划, 同一时候将 strokesArr 笔画数组中的最后一个元素删除。 反之。重做: 即将abandonedStrokesArr (被丢弃的笔画数组)中最后一个元素加入到全部笔画数组中,同一时候将(被丢弃的笔画数组)中的最后一个元素删除。 */ #import <UIKit/UIKit.h> // 自己定义的颜色选择控制器,点击之后,它会告诉代理,选中了什么颜色 @class ColorPickerController; @interface Canvas : UIView #pragma mark - 属性列表 // 标签,显示笔刷大小 @property (nonatomic,retain) IBOutlet UILabel *labelSize; // 滑块 笔刷大小 @property (nonatomic,retain) IBOutlet UISlider *sliderSize; // 三个button,各自是撤销、重做、清除 @property (nonatomic,retain) IBOutlet UIBarButtonItem *undoBtn; @property (nonatomic,retain) IBOutlet UIBarButtonItem *redoBtn; @property (nonatomic,retain) IBOutlet UIBarButtonItem *clearBtn; // toolBar,目的是截图的时候,隐藏掉toolBar @property (nonatomic,retain) IBOutlet UIToolbar *toolBar; #pragma mark - 方法列表 // 初始化全部的准备工作 -(void) viewJustLoaded; // 选择相冊 被点击 -(IBAction) didClickChoosePhoto; // 滑块滑动,设置笔刷大小 -(IBAction) setBrushSize:(UISlider*)sender; // 撤销 被点击 -(IBAction) undo; // 重做 被点击 -(IBAction) redo; // 清除画布 被点击 -(IBAction) clearCanvas; // 保存图片 被点击 -(IBAction) savePic; // 颜色选择 被点击 - (IBAction) didClickColorButton; // 重要~~开放给还有一个控制器调用,它在调用代理时,会传入參数:即选择好的颜色 - (void) pickedColor:(UIColor*)color; @end



    核心代码

    //
    //  Canvas.h
    //  24_Canvas画画板
    //
    //  Created by beyond on 14-8-26.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    /*
     
      这儿仅仅是做演示demo。直接让Canvas与控制器绑定,開始画画,监听事件
     
      假设,要更好的抽取出来,则须要创建一个模型类(model)来提供数据源(比方_strokesArr,_abandonedStrokesArr),供CanvasView显示
     
      UIView的setNeedsDisplay和setNeedsLayout方法
      首先两个方法都是异步运行的。

    而setNeedsDisplay会调用自己主动调用drawRect方法,这样能够拿到 UIGraphicsGetCurrentContext。就能够画画了。

    UIUserInterfaceIdiomPad iPad上专用 */ #import "Canvas.h" #import "ColorPickerController.h" #import "BeyondViewController.h" @interface Canvas ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate> { // 全部笔画 NSMutableArray *_strokesArr; // 丢弃(撤销)的笔画 NSMutableArray *_abandonedStrokesArr; // 当前笔刷颜色 UIColor *_currentColor; // 当前的笔刷大小 float currentSize; // 选中的图片 UIImage *_pickedImg; // 截屏图片 UIImage *_screenImg; // 自己定义的 颜色选择控制器 ColorPickerController *_colorPickerCtrl; // 相片选择器 UIImagePickerController *_imagePickerCtrl; } @end @implementation Canvas #pragma mark - 生命周期方法 // 禁止多点触摸 -(BOOL)isMultipleTouchEnabled { return NO; } // 最重要的绘图方法 - (void) drawRect: (CGRect) rect { // 1.先把获取的图片,画到画布上 [self drawPickedImgToCanvas]; // 2.假设【笔画数组】有笔画字典,则按顺序将笔画取出,画到画布上 [self drawStrokesArrToCanvas]; } // 1.先把获取的图片,画到画布上 - (void)drawPickedImgToCanvas { int width = _pickedImg.size.width; int height = _pickedImg.size.height; CGRect rectForImage = CGRectMake(0, 0, width, height); [_pickedImg drawInRect:rectForImage]; } // 2.假设【笔画数组】有笔画字典,则按顺序将笔画取出,画到画布上 - (void)drawStrokesArrToCanvas { // 假设【笔画数组】为空,则直接返回 if (_strokesArr.count == 0) return; // 遍历【笔画数组】,取出每个笔画字典,每一次迭代,画一个stroke for (NSDictionary *oneStrokeDict in _strokesArr) { // 取出点数组 NSArray *pointsArr = [oneStrokeDict objectForKey:@"points"]; // 取出颜色 UIColor *color = [oneStrokeDict objectForKey:@"color"]; // 取出笔刷尺寸 float size = [[oneStrokeDict objectForKey:@"size"] floatValue]; // 设置颜色 [color set]; // line segments within a single stroke (path) has the same color and line width // 画一个stroke, 一条接着一条,使用圆接头 round joint // 创建一个贝塞尔路径 UIBezierPath* bezierPath = [UIBezierPath bezierPath]; // 点数组 中的第一个,就是 起点 CGPoint startPoint = CGPointFromString([pointsArr objectAtIndex:0]); // 将路径移动到 起点 [bezierPath moveToPoint:startPoint]; // 遍历点数组,将每个点,依次加入到 bezierPath for (int i = 0; i < (pointsArr.count - 1); i++) { // 依次取出下一个点 CGPoint pointNext = CGPointFromString([pointsArr objectAtIndex:i+1]); // 加入到路径 [bezierPath addLineToPoint:pointNext]; } // 设置线宽 bezierPath.lineWidth = size; // 线连接处为 圆结头 bezierPath.lineJoinStyle = kCGLineJoinRound; // 线两端为 圆角 bezierPath.lineCapStyle = kCGLineCapRound; // 调用路径的方法 画出一条线 [bezierPath stroke]; } } // 重要~~~初始化全部东东 -(void) viewJustLoaded { // 1.初始化颜色选择控制器 [self addColorPickerCtrl]; // 2.初始化【相片选择器】 [self addUIImagePickerCtrl]; // 3.其它成员初始化 // 【笔画数组】 _strokesArr = [NSMutableArray array]; // 【被丢弃的笔画数组】 _abandonedStrokesArr = [NSMutableArray array]; // 笔画大小 currentSize = 5.0; // toolBar上笔画标签显示文字 self.labelSize.text = @"Size: 5"; // 设置笔刷 黑色 [self setStrokeColor:[UIColor blackColor]]; // 4.设置重做、撤销、清空三个button的状态 [self updateToolBarBtnStatus]; } // 1.初始化颜色选择控制器 - (void)addColorPickerCtrl { // 1.加入【颜色选择控制器】ColorPickerController。由于要加入到主控制器中 BeyondViewController *mainVC = [BeyondViewController sharedBeyondViewController]; // 初始化自己封装的颜色选择控制器,并设置好代理,目的是颜色设置好了之后,回调告诉当前的canvas画布 _colorPickerCtrl = [[ColorPickerController alloc] init]; _colorPickerCtrl.pickedColorDelegate = self; // 控制器成为父子关系,视图也成为父子关系 [mainVC addChildViewController:_colorPickerCtrl]; [mainVC.view addSubview:_colorPickerCtrl.view]; // 临时隐藏【颜色选择控制器】,仅仅有在点击了ToolBar上面的button时候,才显示出来 _colorPickerCtrl.view.hidden = YES; } // 2.初始化【相片选择器】 - (void)addUIImagePickerCtrl { if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { _imagePickerCtrl = [[UIImagePickerController alloc] init]; _imagePickerCtrl.delegate = self; _imagePickerCtrl.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; // 2) 设置同意改动 // [_imagePickerCtrl setAllowsEditing:YES]; } } // 3.自己定义方法,设置 撤销、重做、清空三个button的可点击状态 - (void)updateToolBarBtnStatus { _redoBtn.enabled = _abandonedStrokesArr.count > 0; _undoBtn.enabled = _strokesArr.count > 0; _clearBtn.enabled = _strokesArr.count > 0; } #pragma mark - 控件连线方法 // 滑块滑动 - (IBAction)setBrushSize:(UISlider*)sender { currentSize = sender.value; self.labelSize.text = [NSString stringWithFormat:@"Size: %.0f",sender.value]; } // 撤销button点击事件 -(IBAction) undo { // 假设笔画数组中有笔画字典 if ([_strokesArr count]>0) { // 最后一个笔画字典,即,被丢弃的笔画字典 NSMutableDictionary* abandonedStrokeDict = [_strokesArr lastObject]; // 将最后一个笔画字典,加入到被丢弃的笔画字典数组里面保存,以供drawRect [_abandonedStrokesArr addObject:abandonedStrokeDict]; // 从全部笔画数组中移除掉最后一笔 [_strokesArr removeLastObject]; // 又一次调用drawRect进行绘制 [self setNeedsDisplay]; } // 2.设置重做、撤销、清空三个button的状态 [self updateToolBarBtnStatus]; } // 重做 -(IBAction) redo { // 假设 被丢弃的笔画数组,里面有值 if ([_abandonedStrokesArr count]>0) { // 取出最后一个被仍进来的 笔画字典,(即最先书写的,并且是在撤销的操作里面,最后被加入到【被丢弃的笔画数组】) NSMutableDictionary* redoStrokeDict = [_abandonedStrokesArr lastObject]; // 将须要重画的笔画字典,加入到【全部笔画数组】中 [_strokesArr addObject:redoStrokeDict]; // 并且,从【被丢弃的笔画数组】中移除,该笔画字典 [_abandonedStrokesArr removeLastObject]; // 又一次调用drawRect进行绘制 [self setNeedsDisplay]; } // 2.设置重做、撤销、清空三个button的状态 [self updateToolBarBtnStatus]; } // 清空画布,仅仅需清空【全部笔画数组】和【被丢弃的笔画数组】 -(IBAction) clearCanvas { // 建议不要将选择出来的背景图片清空,仅仅清空没写好的笔画算了 // _pickedImg = nil; [_strokesArr removeAllObjects]; [_abandonedStrokesArr removeAllObjects]; // 又一次调用drawRect进行绘制 [self setNeedsDisplay]; // 2.设置重做、撤销、清空三个button的状态 [self updateToolBarBtnStatus]; } // 保存图片 -(IBAction) savePic { // 临时移除 工具条 //[_toolBar removeFromSuperview]; // 截图代码 // 1,开启上下文 UIGraphicsBeginImageContext(self.bounds.size); // 2.将图层渲染到上下文 [self.layer renderInContext:UIGraphicsGetCurrentContext()]; // 开启上下文,使用參数之后,截出来的是原图(YES 0.0 质量高) //UIGraphicsBeginImageContextWithOptions(self.frame.size, YES, 0.0); // 3.从上下文中取出图片 _screenImg = UIGraphicsGetImageFromCurrentImageContext(); // 4.关闭上下文 UIGraphicsEndImageContext(); // 又一次加入 工具条,并置最上方 //[self addSubview:_toolBar]; //[self bringSubviewToFront:self.labelSize]; // 调用自己定义方法,保存截屏到相冊 [self performSelector:@selector(saveToPhoto) withObject:nil afterDelay:0.0]; } // 自己定义方法,保存截屏到相冊 -(void) saveToPhoto { // 一句话,写到相冊 UIImageWriteToSavedPhotosAlbum(_screenImg, nil, nil, nil); // UIAlertView 提示成功 UIAlertView* alertView= [[UIAlertView alloc] initWithTitle:nil message:@"Image Saved" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; } // 点击选择颜色button - (IBAction) didClickColorButton { // 显示或隐藏 自己的【颜色选择控制器】 _colorPickerCtrl.view.hidden = !_colorPickerCtrl.view.hidden; } // 当_colorPickerCtrl选择颜色完成,会调用代理 的本方法 - (void) pickedColor:(UIColor*)color { // 将【颜色选择控制器】,回调的颜色,设置到控件上,并隐藏 【颜色选择控制器】 [self setStrokeColor:color]; _colorPickerCtrl.view.hidden = !_colorPickerCtrl.view.hidden; } // 重要,设置笔刷 新的颜色 -(void) setStrokeColor:(UIColor*)newColor { _currentColor = newColor; } // 点击,选择相片button -(IBAction) didClickChoosePhoto { // 展现,相片选择控制器 [self addSubview:_imagePickerCtrl.view]; } #pragma mark - imagePicker代理方法 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { // 必须手动,关闭照片选择器 [picker.view removeFromSuperview]; // 从info字典得到编辑后的照片【UIImagePickerControllerEditedImage】 _pickedImg = [info valueForKey:@"UIImagePickerControllerOriginalImage"]; // 将图片画到画板上去 [self setNeedsDisplay]; } // 【相片选择器】的代理方法,点击取消时,也要隐藏相片选择器 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [_imagePickerCtrl.view removeFromSuperview]; } #pragma mark - 核心代码,重要~~~画布上手势处理 // 手势開始(画笔落下) // 開始一个新的字典,为每一笔,包含点 和 颜色 // Start new dictionary for each touch, with points and color - (void) touchesBegan:(NSSet *) touches withEvent:(UIEvent *) event { // 一个笔画中的全部点,触摸開始时的【起点】 NSMutableArray *pointsArrInOneStroke = [NSMutableArray array]; NSMutableDictionary *strokeDict = [NSMutableDictionary dictionary]; [strokeDict setObject:pointsArrInOneStroke forKey:@"points"]; // 笔的颜色 [strokeDict setObject:_currentColor forKey:@"color"]; // 笔的大小 [strokeDict setObject:[NSNumber numberWithFloat:currentSize] forKey:@"size"]; // 落笔点 CGPoint point = [[touches anyObject] locationInView:self]; [pointsArrInOneStroke addObject:NSStringFromCGPoint(point)]; [_strokesArr addObject:strokeDict]; } // 将每个点加入到 点数组 // Add each point to points array - (void) touchesMoved:(NSSet *) touches withEvent:(UIEvent *) event { // 移动后的一个点 CGPoint point = [[touches anyObject] locationInView:self]; // 前一个点 CGPoint prevPoint = [[touches anyObject] previousLocationInView:self]; // 字典中先前的点数组 NSMutableArray *pointsArrInOneStroke = [[_strokesArr lastObject] objectForKey:@"points"]; // 在后面追加 新的点 [pointsArrInOneStroke addObject:NSStringFromCGPoint(point)]; CGRect rectToRedraw = CGRectMake( ((prevPoint.x>point.x)?point.x:prevPoint.x)-currentSize, ((prevPoint.y>point.y)?point.y:prevPoint.y)-currentSize, fabs(point.x-prevPoint.x)+2*currentSize, fabs(point.y-prevPoint.y)+2*currentSize ); [self setNeedsDisplayInRect:rectToRedraw]; } // 手势结束(画笔抬起) // Send over new trace when the touch ends - (void) touchesEnded:(NSSet *) touches withEvent:(UIEvent *) event { [_abandonedStrokesArr removeAllObjects]; // 2.设置重做、撤销、清空三个button的状态 [self updateToolBarBtnStatus]; } @end




    颜色选择控制器

    ColorPickerController



    //
    //  ColorPickerController.h
    //  24_Canvas画画板
    //
    //  Created by beyond on 14-8-26.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    
    @interface ColorPickerController : UIViewController 
    
    #pragma mark - 属性列表
    // xib上的imgView
    @property (nonatomic,retain) IBOutlet UIImageView *imgView;
    // 代理用weak
    @property (weak) id pickedColorDelegate;
    
    #pragma mark - 方法列表
    // 核心,依据位图引用 创建基于该位图的上下文对象
    - (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef)inImage;
    // 核心,依据触摸点,从上下文中取出相应位置像素点的颜色值
    - (UIColor*) getPixelColorAtLocation:(CGPoint)point;
    
    @end
    



    核心代码

    //
    //  ColorPickerController.m
    //  24_Canvas画画板
    //
    //  Created by beyond on 14-8-26.
    //  Copyright (c) 2014年 com.beyond. All rights reserved.
    //
    
    #import "ColorPickerController.h"
    #import "Canvas.h"
    @implementation ColorPickerController
    
    
    #pragma mark - 点击结束
    - (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
        
    	UITouch* touch = [touches anyObject];
        // tap点击的位置
    	CGPoint point = [touch locationInView:self.imgView];
        
        // 1.调用自己定义方法,从【点】中取颜色
    	UIColor *selectedColor = [self getPixelColorAtLocation:point];
        // 2.告诉代理,解析出来的颜色
    	[_pickedColorDelegate pickedColor:selectedColor];
    }
    
    
    // 核心代码:关于以下两个方法很多其它的具体资料,敬请查阅【iOS Developer Library 】
    #pragma mark - 核心代码,将图片写入内存,再依据【点】中取颜色
    - (UIColor *) getPixelColorAtLocation:(CGPoint)point
    {
    	UIColor *color = nil;
        // 得到取色图片的引用
    	CGImageRef colorImage = _imgView.image.CGImage;
        
    	// Create off screen bitmap context to draw the image into. Format ARGB is 4 bytes for each pixel: Alpa, Red, Green, Blue
        
        // 调用自己定义方法:从_imgView里面的image的引用,创建并返回相应的上下文
    	CGContextRef contexRef = [self createARGBBitmapContextFromImage:colorImage];
        // 假设创建该图片相应的上下文失败
    	if (contexRef == NULL){
            NSLog(@"取色图片--创建相应的上下文失败~");
            return nil;
        }
    	// 准备将【取色图片】写入刚才创建出来的上下文
        size_t w = CGImageGetWidth(colorImage);		// problem!
    	size_t h = CGImageGetHeight(colorImage);
    	CGRect rect = {{0,0},{w,h}}; 
        log_rect(rect)
        // 调试输出rect:--{{0, 0}, {225, 250}}
        
        int bytesPerRow = CGBitmapContextGetBytesPerRow(contexRef);
        log_int(bytesPerRow) //调试输出int:--900
        
        
        
    	// Draw the image to the bitmap context. Once we draw, the memory 
    	// allocated for the context for rendering will then contain the 
    	// raw image data in the specified color space.
        // 将位图写入(渲染)已经分配好的内存区域
    	CGContextDrawImage(contexRef, rect, colorImage);
    	
        // 得到位图上下文 内存数据块的首地址,用指针记住,作为基地址
    	unsigned char* dataPoint = CGBitmapContextGetData (contexRef);
        NSLog(@"----首地址,指针%p",dataPoint);
        // ----首地址,指针0x8b3f000
        
        
        
    	if (dataPoint != NULL) {
    		//offset 即:依据触摸点的xy,定位到位图内存空间中的一个特定像素
    		//4 的意思是每个像素点,占4个字节
            // w是每一行全部点的总数
            // 依据所在行,所在列,算出在内存块中的偏移地址,然后乘以4,由于每个点在内存中占四个字节
    		int offset = 4*((w*round(point.y))+round(point.x));
            // alpha 为内存基地址+偏移地址
    		int alpha =  dataPoint[offset];
            // red 为内存基地址+偏移地址+1   其它相似
    		int red = dataPoint[offset+1];
    		int green = dataPoint[offset+2];
    		int blue = dataPoint[offset+3];
            
    		NSLog(@"偏移地址: %i colors: RGBA %i %i %i  %i",offset,red,green,blue,alpha);
            // offset: 150908 colors: RGB A 255 0 254  255
            
            // 依据RGBA 生成颜色对象
    		color = [UIColor colorWithRed:(red/255.0f) green:(green/255.0f) blue:(blue/255.0f) alpha:(alpha/255.0f)];
    	}
    	
    	// 操作完毕后,释放上下文对象
    	CGContextRelease(contexRef); 
    	// 从内存中释放掉 载入到内存的图像数据
    	if (dataPoint) {
            free(dataPoint);
        }
    	
    	return color;
    }
    // 自己定义方法2:通过_imgView里面的image的引用,创建并返回相应的上下文
    - (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) inImage
    {
    	
        // 要创建的上下文
    	CGContextRef    context = NULL;
        // 色彩空间
    	CGColorSpaceRef colorSpace;
        // 位图数据在内存空间的首地址
    	void *          bitmapData;
        // 每一行的字节数
    	int             bitmapBytesPerRow;
        // 图片总的占的字节数
    	int             bitmapByteCount;
        
    	
    	// 得到图片的宽度和高度,将要使用整个图片,创建上下文
    	size_t pixelsWide = CGImageGetWidth(inImage);
    	size_t pixelsHigh = CGImageGetHeight(inImage);
    	
    	// 每一行占多少字节. 本取色图片中的每个像素点占4个字节;
        // 红 绿 蓝 透明度 各占一个字节(8位  取值范围0~255)
        // 每一行的字节数,由于每个像素点占4个字节(包括RGBA)(当中一个R就是一个字节,占8位,取值是2的8次方 0~255)
    	bitmapBytesPerRow   = (pixelsWide * 4);
        // 图片总的占的字节数
    	bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
    	
    	// 使用指定的 色彩空间(RGB)
    	colorSpace = CGColorSpaceCreateDeviceRGB();
    	if (colorSpace == NULL)
    	{
    		fprintf(stderr, "创建并分配色彩空间 出错
    ");
    		return NULL;
    	}
    	
    	// This is the destination in memory
    	// where any drawing to the bitmap context will be rendered.
        // 为取色图片数据  分配全部的内存空间
        // 全部画到取色图片上下文的操作,都将被渲染到此内存空间
    	bitmapData = malloc( bitmapByteCount );
    	if (bitmapData == NULL) 
    	{
    		fprintf (stderr, "内存空间分配失败~");
    		CGColorSpaceRelease( colorSpace );
    		return NULL;
    	}
    	
    	// 创建位图上下文. 使用 pre-multiplied ARGB, ARGB中的每个成员都占8个bit位,即一字节,一个像素共占4个字节
    	// 不管原取色图片的格式是什么(CMYK或Grayscale),都将通过CGBitmapContextCreate方法,转成指定的ARGB格式
    	context = CGBitmapContextCreate (bitmapData,
    									 pixelsWide,
    									 pixelsHigh,
    									 8,      // bits per component
    									 bitmapBytesPerRow,
    									 colorSpace,
                                        kCGImageAlphaPremultipliedFirst);
    	if (context == NULL)
    	{
    		free (bitmapData);
    		fprintf (stderr, "位图上下文创建失败~");
    	}
    	
    	// 在返回上下文之前 必须记得释放 色彩空间
    	CGColorSpaceRelease( colorSpace );
    	
    	return context;
    }
    
    
    
    
    
    
    @end
    








  • 相关阅读:
    看一下有没有好的解决方案!
    netinet/in.h详细介绍
    【合集】zz数组与指针的艺术深入探索c/c++数组与指针
    struct sockaddr与struct sockaddr_in ,struct sockaddr_un的区别和联系
    C Socket实例
    C语言中malloc与free
    函数fp()、数组a[i]和箭头符号>的由来
    linux gcc编译错误
    怎样检测内存泄露
    dlmalloc解析连载完结【总】
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5109890.html
Copyright © 2011-2022 走看看