功能效果
demo示例
功能分析
功能實現
渲染圖片拆分圖片:
- 拆分方法1:通過圖形看出是一個矩形,而矩形是可以分成兩個三角形和四個頂點,通過此可以用GL渲染出圖片。
拆分三角形
這樣拆分之后雖然可以正常渲染,但是帶來的問題是我的四個頂點都是死的,也就是四個頂點必須是畫布的四個頂點,改變頂點的坐標后只能導致整張畫布的變動,而不是某一個區域的變動,拉伸的話也是整張圖片的拉伸,所以想要實現局部處理的話這種分割方式不可行。
- 拆分方法2:將整張圖片先拆分為三個矩形,然后再把每個矩形拆分成兩個三角形,得到6個三角形,8個頂點,如下圖:
拆分2
這樣一來就可以保證中間的矩形的高度可以任意變化而上下兩部分的高度不變只改變位置,也就是說我們這個DEMO中所做的任何拉伸操作都是對中間矩形的操作,換而言之就是改變最上面的矩形和最下面的矩形之間的距離來達到對中間區域的拉伸和壓縮的目的。根據拆分的方式我們用頂點的坐標創建一個數組
//頂點數組
GL
float vertices[] = { -1.2, -1.2, //左下1.2, -1.2, //右下-1.2, -0.4, //小矩形左下1.2, -0.4, //小矩形右下-1.2, 0.4, //小矩形左上1.2, 0.4, //小矩形右上-1.2, 1.2, //左上1.2, 1.2, //右上
};//填充紋理的數組
GL
float texCoords[] = { 0, 0, //左下 //下標為 0 11, 0, //右下 //下標為2 30, 1.0/3.0, //小矩形左下 //下標為4 51, 1.0/3.0, //小矩形右下 //下標為6 70, 2.0/3.0, //小矩形左上角 //下標為8 91, 2.0/3.0, //小矩形右上角 //下標為10 110, 1, //左上 //下標為12 131, 1, //右上 //下標為14 15
};
復制代碼- 手動選擇區域:通過添加帶有自定義手勢的UIView 來實現拖動修改選擇區域。
*****************CustomPanView代碼******************
@protocol CustomPanViewDelegate <NSObject>/*** 開始拖拽** @param customPanView 自身* @param centerY 自身所在的y坐標*/
- (void)beginDragWithCoustomPanView:(UIView *)customPanView centerY:(CGFloat)centerY;@end@interface CustomPanView : UIView@property (nonatomic, assign) id<CustomPanViewDelegate> delegate;@end
復制代碼*****************CustomPanViewDelegate代碼******************
-(void)beginDragWithCoustomPanView:(UIView *)customPanView centerY:(CGFloat)centerY {// 限制范圍:裁剪區不能大于圖片區域
if (customPanView.center.y >= imageBottom) {customPanView.center = CGPointMake(customPanView.center.x, imageBottom);}
if (customPanView.center.y <= imageTop) {customPanView.center = CGPointMake(customPanView.center.x, imageTop);}// 獲取兩條線的坐標CGFloat topY = _topView.center.y;CGFloat bottomY = _bottomView.center.y;// 根據兩條線的坐標刷新裁剪區域UI[_cutLabel
setFrame:CGRectMake(0, topY < bottomY ? topY : bottomY, SCREEN_WIDTH, fabs(bottomY - topY))];// 算出裁剪起始坐標和結束坐標CGFloat fromPoint = topY < bottomY ? (imageBottom - bottomY) / imageHeight : (imageBottom - topY) / imageHeight;CGFloat toPoint = topY < bottomY ? (imageBottom - topY) / imageHeight : (imageBottom - bottomY) / imageHeight;//將中間的矩形的頂點坐標和坐標聯系裁剪區域聯系起來。[self sendFromePoint:fromPoint endPoint:toPoint];
if (_cutLabel.frame.size.height < 30) { //隱藏文字_cutLabel.text = @
"";}
else {_cutLabel.text = @
"編輯區域";}[self.slider
setValue:0.0 animated:YES];tmpHeight = 0.0f;}
復制代碼使用一個Delegate將拖移后的Y坐標返回,因為是豎直運動的所以我們只關心Y軸坐標。
- 改變大小:通過將UISliderBar的ValueChange和頂點坐標關聯來實現改變頂點坐標,之后調用GLKView 的display的方法來刷新UI,將變化的過程展現出來。
- (void)action:(UISlider *)sender {//判斷是否是向右滑動isRightDirection = sender.value >= judgeDirection ? YES : NO;//所改變的高度changeHeight = sender.value - tmpHeight;//遍歷數組
for (int i = 0; i < 16; i ++) {//將Y坐標篩選出來
if (i % 2 != 0) {//下半部分矩形
if (i <= 7) {//下半部分矩形Y軸做減法減去變化的高度vertices[i] = verticesCopy[i] - changeHeight;//上半部分矩形}
else if (i >= 9) {//上半部分矩形Y軸做加法加上變化的高度vertices[i] = verticesCopy[i] + changeHeight;}}}//縮小時候如果編輯區域已經成為一條線了就不能在縮小了
if (vertices[11] > vertices[7]) {[self.glView display];}}
復制代碼- 通過glReadPixels來從內存中讀取像素數據,GLubyte -> CGImageRef -> UIimage 然后最相關的保存或者其他操作。
- (UIImage *) createImage {int imageY = 0;int imgHeight = 0;
if (isRightDirection) { // 判斷slider滑動方向imageY = fabs(imageTop - fabs(changeHeight * perOpengleseCoordinate)) * screenScale;imgHeight = fabs(imageHeight + 2 * fabs(changeHeight * perOpengleseCoordinate)) * screenScale;}
else {imageY = fabs(imageTop + fabs(changeHeight * perOpengleseCoordinate)) * screenScale;imgHeight = fabs(imageHeight - 2 * fabs(changeHeight * perOpengleseCoordinate)) * screenScale;}int imageWidth = SCREEN_WIDTH * screenScale;int dataLength = imageWidth * imgHeight * 4;GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));glPixelStorei(GL_PACK_ALIGNMENT, 4);glReadPixels(0, imageY, imageWidth, imgHeight, GL_RGBA, GL_UNSIGNED_BYTE, data); //從內存中讀取像素CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();CGImageRef iref = CGImageCreate(imageWidth, imgHeight, 8, 32, imageWidth * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,ref, NULL,
true, kCGRenderingIntentDefault);UIGraphicsBeginImageContext(CGSizeMake(imageWidth, imgHeight));CGContextRef cgcontext = UIGraphicsGetCurrentContext();CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);CGContextDrawImage(cgcontext, CGRectMake(0, 0, imageWidth, imgHeight), iref);CGImageRef imageMasked = CGBitmapContextCreateImage(cgcontext);UIImage * image = [UIImage imageWithCGImage:imageMasked scale:screenScale orientation:UIImageOrientationUp];UIGraphicsEndImageContext();free(data);CFRelease(ref);CFRelease(colorspace);CGImageRelease(iref);
return image;}
復制代碼我的簡書同步更新哦 www.jianshu.com/u/fd21f41fb…
總結
以上是生活随笔為你收集整理的iOS中使用OpenGL 实现增高功能的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。