iOS疯狂详解之自动布局(autolayout)下图片编辑器的实现

iOS 图片编辑——滤镜 iOS中涉及图片编辑中最常见的一种就是滤镜 如下图 首先 ,我们打开Xcode 新建项目  起名:testImageFilterProcess1 拖入几个必要代码(见demo。demo下载地址见QQ群空间:414319235) 拖入过程弹出的选择框选择如下 接下来,我们在默认生成的Vi 阅读详情

在大部分APP(尤其是社交类的,如qq)经常会有更换头像的场景:点击用户加载头像,加载出系统图片,用户点击选中某张图片之后,可以对图片进行放缩和拖动,已更改圆形裁剪框圈定的图片部分。如下图即为qq的头像选取编辑界面:

20141012114535375.gif

图1.qq照片编辑界面

界面中可以对图片进行放大、缩小,拖动,白色圆环区域表示点击确定时将要裁剪的范围。留意上图的动画,qq总是能够确保圆环完全被图片所覆盖,如果拖动或者放缩使得图片以外的黑色区域进入了圆环,图片会自动弹回刚好能够完全覆盖的状态,鉴于优快云上传图片2M的限制,上面的gif图很短,感兴趣的同学可以打开QQ自己体验一把(在修改个人头像功能中)。

现在我们也要实现一个类似功能的界面,并且是在autolayout环境下,同时支持横竖屏,这比QQ的图片选取页面又复杂了一些:QQ只支持竖屏的情况,不需要考虑横屏时的情况和横竖屏切换的问题。下面详细讨论。

一、预期效果

用户从相册或者相机中选取/拍摄一张照片,加载到图片编辑界面,用户可以拖动、放缩照片,使圆形选取框中截图到合适的图像作为用户头像。效果图如下图所示:

用户在拖动、放缩时要保证圆环区域全部被图片所覆盖,这样才能确保裁剪出来的照片刚好能够撑满整个圆形区域。同时,因为我们支持横屏布局,因此还要确保竖屏切换横屏(或者反之)之后,圆环仍在正确的区域。

20141012135048671.png

图2.竖屏效果
20141012135124296.png

图3.横屏效果

整个界面满足了上述用户交互需求之外,还要在用户点击确定的时候,将圆形区域的图片裁剪下来,实现图片编辑的功能。

二、实现细节

2.1基本思路

在实现上,这个页面可以分为两大块:一块是scrollview的设置:contentSize、contentInset、zoomScale等等;另一块是剪切框的实现(白色圆环、外围半透明蒙层),以及横竖屏切换时剪切框如何变化等;而这两块又不是完全独立的:scrollview的很多交互都依赖于剪切框:最小放缩不能小于剪切框、移动不能超出剪切框的范围等。可以认为,scrollview的属性依赖于剪切框的属性。而剪切框在横屏或者竖屏的时候大小位置是保持不变的,因此,我们很自然的得到这样一个思路:先确定剪切框,横竖屏都没问题了,再通过剪切框确定scrollview。

2.2剪切框的实现

从图二中可以看出剪切框是一个比较特殊的界面:圆形虚线框内部是完全透明的(clearColor or alpha = 0),而外围的填充部分则是半透明效果(blackColor and alpha = 0.2),常规的通过view的嵌套设置alpha、backgroundColor和layer.cornerRadius是不行的,因为view的alpha属性具有“遗传性”:父view的alpha将直接作用于所有的子view上去,这时我们就要考虑通过更底层的绘图方式直接在一个view上完成剪切框的绘制工作。

我们在storyboard中添加一个view(称之为:maskView),添加约束使其和scrollview大小、尺寸完全保持一致。将这个view的class改为TTPhotoMaskView:一个我们定制的view,在其drawRect方法中,绘制剪切框,绘制示意图如下:

360桌面截图20141014103117.jpg

图4.剪切框绘制

1.绘制两条封闭的线,一条是方形的,刚好覆盖整个view的边界,还一条是圆形的虚线裁剪框;

2.使用奇偶原则对这两条封闭曲线进行色彩填充,使得方框和圆形框之间的区域填充(黑色,alpha=0.2),而圆形框内部不进行填充(透明)。

具体实现代码如下:

-(void)drawRect:(CGRect)rect  
{  
    CGFloat width = rect.size.width;  
    CGFloat height = rect.size.height;  
    //pickingFieldWidth:圆形框的直径  
    CGFloat pickingFieldWidth = width < height ? (width - kWidthGap) : (height - kHeightGap);  
    CGContextRef contextRef = UIGraphicsGetCurrentContext();  
    CGContextSaveGState(contextRef);  
    CGContextSetRGBFillColor(contextRef, 0, 0, 0, 0.35);  
    CGContextSetLineWidth(contextRef, 3);  
    //计算圆形框的外切正方形的frame:  
    self.pickingFieldRect = CGRectMake((width - pickingFieldWidth) / 2, (height - pickingFieldWidth) / 2, pickingFieldWidth, pickingFieldWidth);  
    //创建圆形框UIBezierPath:  
    UIBezierPath *pickingFieldPath = [UIBezierPath bezierPathWithOvalInRect:self.pickingFieldRect];  
    //创建外围大方框UIBezierPath:  
    UIBezierPath *bezierPathRect = [UIBezierPath bezierPathWithRect:rect];  
    //将圆形框path添加到大方框path上去,以便下面用奇偶填充法则进行区域填充:  
    [bezierPathRect appendPath:pickingFieldPath];  
    //填充使用奇偶法则  
    bezierPathRect.usesEvenOddFillRule = YES;  
    [bezierPathRect fill];  
    CGContextSetLineWidth(contextRef, 2);  
    CGContextSetRGBStrokeColor(contextRef, 255, 255, 255, 1);  
    CGFloat dash[2] = {4,4};  
    [pickingFieldPath setLineDash:dash count:2 phase:0];  
    [pickingFieldPath stroke];  
    CGContextRestoreGState(contextRef);  
    self.layer.contentsGravity = kCAGravityCenter;  
}

现在再来考虑如何处理横竖屏的问题:我们的剪切框是直接通过UIView的drawRect方法直接手绘上去的,因此无法通过自动布局(autolayout)对剪切框进行重新布局。

解决的办法是在屏幕发生横竖屏切换的时候重新绘制圆形剪切框。在iOS8中不再使用willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration来获取屏幕旋转事件了,iOS8以后的使用新的willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id)coordinator来代替。

因此我们在这个方法中,强制裁剪框重绘(maskview):

#pragma mark - UIContentContainer protocol  
- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id)coordinator  
{  
    [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];  
    [self.maskView setNeedsDisplay];  
}

这样我们的剪切框就顺利完成了,接下来我们来设置scrollview,使其满足我们的交互预期。

2.3 scrollview的设置

首先来看一下整个view的层级结构:scrollview有一个撑满整个scrollview的imageView作为scrollview的content view,在scrollView之上盖着一个剪切框的view(mask view),这三个view都通过约束保持和根view的bounds一致。

20141013142547328.png

图5.view的层级结构

上面提到,scrollview的各种属性的设置都要依赖于手绘出的剪切框。而圆形剪切框的位置、大小在每次转屏之后可能发生变化,因此我们必须要在每次maskView的drawRect方法调用之后都重新调整一下scrollview的属性。因此我们在maskView中添加一个代理,将这个代理设置为maskview所在的viewController,每次当重绘发生后就通过代理方法通知viewcontroller调整scrollview的各项属性:

//  TTPhotoMaskView.h  
@protocol TTPhotoMaskViewDelegate   
  
- (void)pickingFieldRectChangedTo:(CGRect) rect;  
  
@end  
  
@interface TTPhotoMaskView : UIView  
  
@property (nonatomic, weak) id  delegate;  
  
@end

在maskView的drawRect方法中添加:其中pickingFieldRect即为圆环剪切框的“frame”,包含其相对于maskView的origin和size信息。

    if ([self.delegate respondsToSelector:@selector(pickingFieldRectChangedTo:)]) {  
        [self.delegate pickingFieldRectChangedTo:self.pickingFieldRect];  
    }

接下来就是在我们的viewController中实现pickingFieldRectChangedTo方法,调整scrollView:

#pragma mark - TTPhotoMaskViewDelegate  
- (void)pickingFieldRectChangedTo:(CGRect)rect  
{  
    self.pickingFieldRect = rect;  
    CGFloat topGap = rect.origin.y;  
    CGFloat leftGap = rect.origin.x;  
    self.scrollView.scrollIndicatorInsets = UIEdgeInsetsMake(topGap, leftGap, topGap, leftGap);  
    //step 1: setup contentInset  
    self.scrollView.contentInset = UIEdgeInsetsMake(topGap, leftGap, topGap, leftGap);  
  
    CGFloat maskCircleWidth = rect.size.width;  
    CGSize imageSize = self.originImage.size;  
    //setp 2: setup contentSize:  
    self.scrollView.contentSize = imageSize;  
    CGFloat minimunZoomScale = imageSize.width < imageSize.height ? maskCircleWidth / imageSize.width : maskCircleWidth / imageSize.height;  
    CGFloat maximumZoomScale = 5;  
    //step 3: setup minimum and maximum zoomScale  
    self.scrollView.minimumZoomScale = minimunZoomScale;  
    self.scrollView.maximumZoomScale = maximumZoomScale;  
    self.scrollView.zoomScale = self.scrollView.zoomScale < minimunZoomScale ? minimunZoomScale : self.scrollView.zoomScale;  
  
    //step 4: setup current zoom scale if needed:  
    if (self.needAdjustScrollViewZoomScale) {  
        CGFloat temp = self.view.bounds.size.width < self.view.bounds.size.height ? self.view.bounds.size.width : self.view.bounds.size.height;  
        minimunZoomScale = imageSize.width < imageSize.height ? temp / imageSize.width : temp / imageSize.height;  
        self.scrollView.zoomScale = minimunZoomScale;  
        self.needAdjustScrollViewZoomScale = NO;  
    }  
}

下面来详细解析一下上面每一步设置的作用,首先以一张苹果官方文档(Scroll View Programming Guide for iOS)上的图片来简单看一下contentSize和contentInset的意义和作用:

20141013143855807.jpg

图6.UIScrollView的contentSize和contentInset属性示意图

contentSize是你在scrollView中要展示的内容(content)的大小,具体值要根据content的尺寸而定,我们这里是要完整的无压缩的展示一个图片的内容,因此这里在step 2中将contentSize设为图片(image.size)的size同等大小。

contentInset可以理解为展示内容的上下左右“留白”的间距,默认值为(0,0,0,0),contentInset所标示的留白加上contentSize才是一个scrollView所能滑动的全部区域。这里我们不想让content(图片)的滑动区域超出圆形剪切框的位置,可以通过巧妙的讲剪切框圆环和view的上下左右边缘的间距作为scrollView的contentInset,这就是step 1做的事情,它确保了手指在图片上拖动的时候圆形剪切框总能填满图片的内容。

scrollView对于放大缩小的支持非常简单,你只需设置放缩的最大和最小倍数,然后在代理函数(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView中返回要缩放的view即可。这里主要需要确定的时scrollview的最小缩放尺寸,以满足当放缩到最小时刚好图片较短的一个维度(长或者宽)和圆形剪切框相切,这是能够放缩的最小值,因为如果再缩小图片就无法填满剪切框了:

360桌面截图20141014104104.jpg

图7.放缩到最小时,剪切框必须要和较短的一边相切

step 4只在viewDidLoad的时候执行,也即第一次进入图片编辑页面的时候,需要强制调整一下scrollview的当前zoomScale,使得图片在一个合适的尺寸显示出来。

至此,整个功能完成,运行一下程序,看一下效果,达到了预期:

20141013152324598.gif

图8.转屏效果

20141013152747427.gif

图9.拖动和缩放

三、总结

将图片加载进scrollview,对其放缩、拖动然后裁剪其中一部分是图片编辑器的主要功能,看似简单的功能需求,细究起来却处处是坑,必须要深入的思考其中的每一个细节,利用好UIView的drawRect方法,结合使用scrollview的特性方能得以实现。

本示例主要有以下两点值得关注:

1.圆形剪切框的实现,以及在autolayout环境下旋转屏后剪切框的处理;

2.scrollView的属性设置,必须要结合所加载图片的实际尺寸、圆形剪切框的位置和大小信息来动态的调整scrollView的contentSize、contentInset等属性。

iOS 图片编辑——缩放剪切 iOS项目中 如果涉及编辑图片的 可能首先会用到就是图片的缩放 这里我们给大家共享一个开源代码 实现图片的缩放,旋转,按照设定比例调整缩放等功能     首先我们使用Xcode 新建一个项目 起名 tetsImageEdit1 新建好后 我们有几个文件需要拖入项目(文件包含在源代码中,源码将上传到群空间:414319235) 阅读详情

相关推荐

iOS 图片编辑——涂鸦——在图片上添加文字

前面几节讲了图片上画线 这一节 我们简单讲一讲 给图片上添加文字的方法 我们继续使用上节的代码(代码下载地址见上节末尾   http://blog.youkuaiyun.com/lwjok2007/article/details/50887396) 首先我们将添加文字的View单独抽象出现实现 创建一个类 继承自UIView 起名: AddText 定义一个协议 当输入完成之后 将内

7815

自动布局(autolayout)环境下图片编辑器的实现

在大部分APP(尤其是社交类的,如qq)经常会有更换头像的场景:点击用户加载头像,加载出系统图片,用户点击选中某张图片之后,可以对图片进行放缩和拖动,已更改圆形裁剪框圈定的图片部分。如下图即为qq的头像选取编辑界面: 界面中可以对图片进行放大、缩小,拖动,白色圆环区域表示点击确定时将要裁剪的范围。留意上图的动画,qq总是能够确保圆环完全被图片所覆盖,如果拖动或者放缩使得图片以

jys1115的专栏 897

做一个属于自己的照片编辑器

做一个属于自己的照片编辑器使用过UIImagePickerController的童鞋们都知道,iOS在从相册或者摄像头后选择照片后可以编辑(选择照片的一部分剪切下来),只需要将UIImagePickerController的allowsEditing属性设为YES即可。哇,so easy!真的如此简单吗?你如果这样想就可以不要继续看下去了。用过的童鞋应该都会这么认为(至少我是这么认为)系统的那个渣渣

u014210007的专栏 1309

Android播放GIF图片

public class GIFView extends View implements Runnable { private Bitmap bmb; private GIFDecode decode; public GIFView(Context context) { super(context); decode = new GIFDecode(); decode.read(

twoicewoo的专栏 1810

iOS图片编辑(CIFilter)

在iOS中开发过程中,如果你想对图片进行简单的处理,那么很简单,苹果帮我们封装了一套简单易用的API——CIFilter。 使用CIFilter你可以做到:调节图片亮度、对比度、饱和度等图片基本的操作;使用模糊、锐化、高反差等对图片进行滤镜处理。 一、基本概念 1、CIFilterCategory。 图片处理的方式方法种类繁多,在CIFiler中是如何对这么多的图片处理方式进行归类...

wentianen的博客 2054

R语言layout函数处理可视化图像布局实战

R语言layout函数处理可视化图像布局实战 目录 R语言layout函数处理可视化图像布局实战 #基本语法 #layout定义位置矩阵并可视化 #layout定义包含空位的位置矩阵并可视化 #layout定义布局的宽度和高度 #基本语法 layout(position_matrix) # Basic R syntax of layout function #layout定义位置矩阵并可视化 layout_ma...

data+scenario+science+insight 1038

【亲测免费】 iOS 图片编辑器

iOS Image Editor 是一个开源的 iOS 图像编辑库,它允许您在 iOS 应用程序中实现图像编辑功能。 功能特性 支持多种图片格式(JPEG、PNG、BMP 和 TIFF) 可以裁剪、旋转、调整亮度和对比度等操作 支持添加滤镜效果 支持自定义画笔和橡皮擦工具 可以保存编辑后的图片到相册或者分享给其他人 使用场景 iOS Image Editor 可以用于各种需要在移动设备上处理图...

gitblog_00052的博客 727

ios应用源码之一个简单的图片编辑器 2018127

ios应用源码之一个简单的图片编辑器 .

iOS图片编辑功能实现

图片加标签;标签可以编辑 https://github.com/shumingli/waterMark 1. 编辑效果;图片可以放到、缩小、旋转 2. 保存相册效果 转载于:https://www.cnblogs.com/lishuming/p/5531786.html...

weixin_33830216的博客 1295

CH592F RISC-V蓝牙LED灯设计:WS2812B驱动与微信小程序控制

蓝牙低功耗(BLE)是嵌入式物联网设备主流无线通信技术,其核心在于协议栈轻量化、射频稳定性与外设协同调度。基于RISC-V内核的蓝牙SoC(如CH592F)凭借高集成度、低待机电流和免外部巴伦的射频设计,显著降低硬件复杂度与BOM成本;而WS2812B作为单线级联RGB LED,依赖微秒级精准时序,需借助定时器+DMA机制规避CPU干预,保障动态效果流畅性。该方案融合电容触摸交互、GATT服务自定义与微信小程序标准Bluetooth API对接,适用于智能照明、DIY彩灯及教学实践等场景,是BLE+LED实

weixin_31163455的博客 433

Drupal远程代码执行漏洞(CVE-2018-7600)实战复现:从检测到写入WebShell的全过程

本文详细解析了Drupal远程代码执行漏洞(CVE-2018-7600)的实战复现过程,从环境搭建、漏洞检测到WebShell写入的全流程。该高危漏洞影响Drupal 6.x至8.x版本,允许攻击者未经授权执行任意代码。文章提供了多种POC构造方法和高级利用技巧,帮助安全研究人员深入理解漏洞原理并掌握验证技术。

weixin_29322553的博客 275

iOS 实现图文编辑

摸索一下使用原生控件实现图文编辑,直接开搞。 首先搞个文本输入和选择图片的按钮: @property (nonatomic, strong) UITextView * tv; @property (nonatomic, strong) UIButton * selectImageBtn; ...

chensidu0288的博客 648

3台虚拟机部署Doris详细文档(含校验步骤)

摘要:本文详细介绍了Apache Doris在3台虚拟机上的集群部署方案。采用1主FE+1从FE+1观察者FE+3BE的混合部署模式,确保元数据高可用性。硬件配置建议测试环境4核16GB内存,生产环境8核64GB内存。部署步骤包括系统环境配置(关闭防火墙、内核参数优化)、FE/BE节点配置启动、集群初始化验证等。重点配置了IP白名单(172.30.0.115)和数据目录(/data/doris)。通过MySQL客户端和WebUI可监控集群状态,实现千万级数据的实时分析能力,后续可通过增加BE节点线性扩展。

weixin_41026747的博客 931

iOS 自定义相册图片编辑页面

//从相册中选取图片或拍照 - (void)btnActionForEditPortrait:(id) sender {     UIImagePickerController *picker = [[UIImagePickerController alloc] init];     picker.delegate = self;     picker.sourceType

1万+

ADS124S08配置避坑指南:从SPI时序到寄存器设置,手把手教你调通24位ADC

本文详细解析了ADS124S08 24位ADC的SPI时序配置、寄存器设置及外围电路设计中的关键细节,帮助工程师避开常见陷阱。从SPI通信模式选择到DRDY引脚读取优化,再到基准电压启动时间调整,提供了实战验证的解决方案,确保高精度数据采集的稳定性。

weixin_29192365的博客 285

SAP 财务快速记账之--科目分配模型(Account assignment model )

SAP FICO 运维解决方案

lijinbao171022的博客 1765

图片编辑,涂鸦。仿qq截图

模仿qq截图,并对截图后的图片进行编辑自己做了一个可以从相机,相册中获取图片并对图片进行编辑的功能模块。 这个是效果图。 下面直接上代码。 package com.example.camera; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; impor

qq_28656671的博客 4378

基于STM32、HAL库的MCP4651-503E/ST数字电位器驱动程序设计

@param channel: 通道 (0: A通道, 1: B通道)* @param channel: 通道 (0: A通道, 1: B通道)// SPI1 SCK/MISO/MOSI引脚配置。* @param hmcp: MCP4651句柄。* @param hmcp: MCP4651句柄。* @param hmcp: MCP4651句柄。* @param hmcp: MCP4651句柄。* @param hmcp: MCP4651句柄。* @param hspi: SPI句柄。

corlin6688的博客 136

iOS开发技巧(系列十五:autolayout自动布局)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34406061的博客 170

基于ENVI完成影像的去云操作以及后续处理

利用ENVI完成重采样影像的去云操作 由于SNAP重采样之后的影像是分波段保存的,ENVI的波段运算工具一次也只能输出一个波段,所以去云的操作分波段进行,原理是掩膜法 下面是打开所有波段后的界面 去云的依据是以quality_scene_classification栅格文件为基础,该文件是哨兵2数据自带的场景质量分类图,包含12个级别,可以通过SNAP软件查看,如下图所示: 对于去云操作而言,我们只需要DARK_FEATURE_SHADOW(地形等),CLOUD_SHADOW(云阴影)、CL

lemon_tttea的博客 2万+

OpenClaw三层记忆系统:让你的AI助理记住你的习惯,越用越顺手

对于更早的、已经移出滑动窗口的对话内容,我们没有直接丢弃,而是用大模型做摘要压缩,只保留核心信息,然后把摘要存入短期会话记忆的末尾,或者长期用户记忆。比如,10轮之前的对话内容,我们会压缩成:“用户之前查询了仓山万达店4月1日-4月7日的库存数据,对报表的要求是纯文本,不要Markdown”,既保留了核心信息,又不会占用太多上下文窗口。如果说Agent的执行链路是AI的“骨架”,工具调用体系是AI的“手脚”,那么记忆系统就是AI的“大脑”

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 378

IOS 代码实现自动布局(视图尺寸自动调整)

如果视图是代码实现的,而非xib实现,加载视图时要自动调整的大小需要用到视图(UIView)的两个属性:autoresizesSubviews与autoresizingMask autoresizesSubviews属性:是个BOOL类型,设置是否该视图的子视图自动调整大小,YES则其子视图会根据autoresizingMask属性的值自动进行尺寸调整。 autoresizingMas

dlm_211314的专栏 1753

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

iOS 图片编辑——涂鸦

iOS图片编辑前面我们讲了 图片的缩放 旋转: http://blog.youkuaiyun.com/lwjok2007/article/details/50845510 滤镜:http://blog.youkuaiyun.com/lwjok2007/article/details/50853878 接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线 创建项目 起名testAddLine

4975

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

内存恶鬼drawRect - 谈画图功能的内存优化

作者介绍 作者:毕洪博 ( @毕洪博 ),iOS 开发者,pop Art 追随者。现在正在鼓捣 AVFoundation,博客 bihongbo.com, 欢迎大家找我讨论技术。 作者已将本文在微信公众平台的发表权「独家代理」给 iOS 开发微信公共号,本文的打赏归毕洪博所有,以下是文章正文。 正文 标题有点吓人,但是对于drawRect的评价倒是一点都不过分。在平日的开发

jijiji000111的专栏 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

IOS 图片的编辑(可删除或从相册添加图片),主要是可以在初始化时添加图片

摘要: 直接copy代码运行就可以了,图片自己去找 // // XMHFlowLayout.h // 自定义CollectionViewFlowLayout // // Created by 徐茂怀 on 16/6/1. // Copyright © 2016年 徐茂怀. All rights reserved. // #import @class XMHFlowL

甜吖~的博客 2575
上一篇: iOS疯狂详解之第三方微信授权登录的iOS代码分析
下一篇: iOS疯狂详解之imageIO完成渐进加载图片
吊炸天-狂人
博客等级 码龄12年 87粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值