图片处理

1~图片压缩

 (1)UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];//

    NSData *imageData = UIImageJPEGRepresentation(image, 0.5);

    UIImage *curimage = [UIImage imageWithData:imageData];

在Iphone上有两种读取图片数据的简单方法: 

UIImageJPEGRepresentation和UIImagePNGRepresentation. 

UIImageJPEGRepresentation函数需要两个参数:图片的引用和压缩系数.而UIImagePNGRepresentation只需要图片引用作为参数.通过在实际使用过程中,比较发现: UIImagePNGRepresentation(UIImage* image) 要比UIImageJPEGRepresentation(UIImage* image, 1.0) 返回的图片数据量大很多.譬如,同样是读取摄像头拍摄的同样景色的照片, UIImagePNGRepresentation()返回的数据量大小为199K ,而 UIImageJPEGRepresentation(UIImage* image, 1.0)返回的数据量大小只为140KB,比前者少了50多KB.如果对图片的清晰度要求不高,还可以通过设置 UIImageJPEGRepresentation函数的第二个参数,大幅度降低图片数据量.譬如,刚才拍摄的图片, 通过调用UIImageJPEGRepresentation(UIImage* image, 1.0)读取数据时,返回的数据大小为140KB,但更改压缩系数后,通过调用UIImageJPEGRepresentation(UIImage* image, 0.5)读取数据时,返回的数据大小只有11KB多,大大压缩了图片的数据量 ,而且从视角角度看,图片的质量并没有明显的降低.因此,在读取图片数据内容时,建议优先使用UIImageJPEGRepresentation,并可根据自己的实际使用场景,设置压缩系数,进一步降低图片数据量大小.

方法二

image3 = [UploadClassViewCTRL thumbnailWithImage1:image1 size:CGSizeMake(image1.size.width/2, image1.size.height/2)];

+ (UIImage *)thumbnailWithImage1:(UIImage *)image size:(CGSize)asize

{

    UIImage *newimage;

    if (nil == image) {

        newimage = nil;

    }

    else{

        UIGraphicsBeginImageContext(asize);

        [image drawInRect:CGRectMake(0, 0, asize.width, asize.height)];

        newimage = UIGraphicsGetImageFromCurrentImageContext();

        UIGraphicsEndImageContext();

    }

    return newimage;

}

2~图片旋转

UIImage * myimage = [UIImage imageWithCGImage:[image CGImage] scale:1 orientation:UIImageOrientationRight];

        [self.HeadImageView setImage:myimage];

(2)

- (UIImage *)fixOrientation:(UIImage*)myImage {

    

    // No-op if the orientation is already correct

    if (myImage.imageOrientation == UIImageOrientationUp) return myImage;

    

    // We need to calculate the proper transformation to make the image upright.

    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.

    CGAffineTransform transform = CGAffineTransformIdentity;

    

    switch (myImage.imageOrientation) {

        case UIImageOrientationDown:

        case UIImageOrientationDownMirrored:

            transform = CGAffineTransformTranslate(transform, myImage.size.width, myImage.size.height);

            transform = CGAffineTransformRotate(transform, M_PI);

            break;

            

        case UIImageOrientationLeft:

        case UIImageOrientationLeftMirrored:

            transform = CGAffineTransformTranslate(transform, myImage.size.width, 0);

            transform = CGAffineTransformRotate(transform, M_PI_2);

            break;

            

        case UIImageOrientationRight:

        case UIImageOrientationRightMirrored:

            transform = CGAffineTransformTranslate(transform, 0, myImage.size.height);

            transform = CGAffineTransformRotate(transform, -M_PI_2);

            break;

    }

    

    switch (myImage.imageOrientation) {

        case UIImageOrientationUpMirrored:

        case UIImageOrientationDownMirrored:

            transform = CGAffineTransformTranslate(transform, myImage.size.width, 0);

            transform = CGAffineTransformScale(transform, -1, 1);

            break;

            

        case UIImageOrientationLeftMirrored:

        case UIImageOrientationRightMirrored:

            transform = CGAffineTransformTranslate(transform, myImage.size.height, 0);

            transform = CGAffineTransformScale(transform, -1, 1);

            break;

    }

    

    // Now we draw the underlying CGImage into a new context, applying the transform

    // calculated above.

    CGContextRef ctx = CGBitmapContextCreate(NULL, myImage.size.width, myImage.size.height,

                                             CGImageGetBitsPerComponent(myImage.CGImage), 0,

                                             CGImageGetColorSpace(myImage.CGImage),

                                             CGImageGetBitmapInfo(myImage.CGImage));

    CGContextConcatCTM(ctx, transform);

    switch (myImage.imageOrientation) {

        case UIImageOrientationLeft:

        case UIImageOrientationLeftMirrored:

        case UIImageOrientationRight:

        case UIImageOrientationRightMirrored:

            // Grr...

            CGContextDrawImage(ctx, CGRectMake(0,0,myImage.size.height,myImage.size.width), myImage.CGImage);

            break;

            

        default:

            CGContextDrawImage(ctx, CGRectMake(0,0,myImage.size.width,myImage.size.height), myImage.CGImage);

            break;

    }

    

    // And now we just create a new UIImage from the drawing context

    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);

    UIImage *img = [UIImage imageWithCGImage:cgimg];

    CGContextRelease(ctx);

    CGImageRelease(cgimg);

    return img;

}

3~设置默认图

    NSURL *urlhead = [NSURL URLWithString:[dic valueForKey:@"user_photo"]];

    [self.ImageHead setImageWithURL:urlhead placeholderImage:[UIImage imageNamed:@"doctor.jpg"]];//imageHead 为UIimageView类型

4~IOS与图片内存
在IOS上,图片会被自动缩放到2的N次方大小。比如一张1024*1025的图片,占用的内存与一张1024*2048的图片是一致的。图片占用内存大小的计算的公式是;长*宽*4。这样一张512*512 占用的内存就是 512*512*4 = 1M。其他尺寸以此类推。(ps:IOS上支持的最大尺寸为2048*2048)。
5~图片的缓存

在开发移动应用的时候比如Android,IOS,因为手机流量、网速、内存等这些因素,当我们的移动应用是针对互联网,并要频繁访问网络的话,对网络优化这块就显得尤为重要了。

比如某个应用要经常显示网络图片,就不能每次显示图片都去网络上下载,那太耗费时间也太耗费流量,这时就要对网络图片进行缓存了,以下是我对IOS网络图片缓存的一些见解,有不足之处,欢迎大家指出来,一起探讨。

处理网络图片缓存步骤:

1、根据图片URL查找内存是否有这张图片,有则返回图片,没有则进入第二步

2、查找物理存储是否有这张图片,有则返回图片,没有则进入第三步

3、从网络上下载该图片,下载完后保存到内存和物理存储上,并返回该图片

注:因为URL包含特殊字符和长度不确定,要对URL进行MD5处理或其他处理

下面是针对以上步骤的代码讲解:

1、内存缓存图片处理

使用NSMutableDictionary存储图片UIImage,数组的Key为该图片的URL地址

//缓存图片到内存上
[plain] view plaincopy
  1. [memCache setObject:image forKey:key];  

2、物理缓存图片处理

把图片保持到物理存储设备上,则直接使用NSFileManager,把URL作为文件名保存

3、网络图片下载处理

图片使用异步下载,下载完后把图片保持到NSMutableDictionary和物理存储上

以下是摘自SDWebImageleik网络图片缓存处理的一个类,有详细注释

.h文件

[plain] view plaincopy
  1. @interface SDImageCache : NSObject  
  2. {  
  3.     NSMutableDictionary *memCache;//内存缓存图片引用  
  4.     NSString *diskCachePath;//物理缓存路径  
  5.     NSOperationQueue *cacheInQueue, *cacheOutQueue;  
  6. }  
  7.   
  8. + (SDImageCache *)sharedImageCache;  
  9.   
  10. //保存图片  
  11. - (void)storeImage:(UIImage *)image forKey:(NSString *)key;  
  12.   
  13. //保存图片,并选择是否保存到物理存储上  
  14. - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;  
  15.   
  16. //保存图片,可以选择把NSData数据保存到物理存储上  
  17. - (void)storeImage:(UIImage *)image imageData:(NSData *)data forKey:(NSString *)key toDisk:(BOOL)toDisk;  
  18.   
  19. //通过key返回UIImage  
  20. - (UIImage *)imageFromKey:(NSString *)key;  
  21.   
  22. //如果获取内存图片失败,是否可以在物理存储上查找  
  23. - (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk;  
  24.   
  25.   
  26. - (void)queryDiskCacheForKey:(NSString *)key delegate:(id <SDImageCacheDelegate>)delegate userInfo:(NSDictionary *)info;  
  27.   
  28. //清除key索引的图片  
  29. - (void)removeImageForKey:(NSString *)key;  
  30. //清除内存图片  
  31. - (void)clearMemory;  
  32. //清除物理缓存  
  33. - (void)clearDisk;  
  34. //清除过期物理缓存  
  35. - (void)cleanDisk;  
  36.   
  37. @end  

.m文件
[plain] view plaincopy
  1. @implementation SDImageCache  
  2.   
  3. #pragma mark NSObject  
  4.   
  5. - (id)init  
  6. {  
  7.     if ((self = [super init]))  
  8.     {  
  9.         // Init the memory cache  
  10.         memCache = [[NSMutableDictionary alloc] init];  
  11.           
  12.         // Init the disk cache  
  13.         NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);  
  14.         diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];  
  15.           
  16.         if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath])  
  17.         {  
  18.             [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath  
  19.                                       withIntermediateDirectories:YES  
  20.                                                        attributes:nil  
  21.                                                             error:NULL];  
  22.         }  
  23.           
  24.         // Init the operation queue  
  25.         cacheInQueue = [[NSOperationQueue alloc] init];  
  26.         cacheInQueue.maxConcurrentOperationCount = 1;  
  27.         cacheOutQueue = [[NSOperationQueue alloc] init];  
  28.         cacheOutQueue.maxConcurrentOperationCount = 1;  
  29.           
  30. #if TARGET_OS_IPHONE  
  31.         // Subscribe to app events  
  32.         [[NSNotificationCenter defaultCenter] addObserver:self  
  33.                                                  selector:@selector(clearMemory)  
  34.                                                      name:UIApplicationDidReceiveMemoryWarningNotification  
  35.                                                    object:nil];  
  36.           
  37.         [[NSNotificationCenter defaultCenter] addObserver:self  
  38.                                                  selector:@selector(cleanDisk)  
  39.                                                      name:UIApplicationWillTerminateNotification  
  40.                                                    object:nil];  
  41.           
  42. #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0  
  43.         UIDevice *device = [UIDevice currentDevice];  
  44.         if ([device respondsToSelector:@selector(isMultitaskingSupported)] && device.multitaskingSupported)  
  45.         {  
  46.             // When in background, clean memory in order to have less chance to be killed  
  47.             [[NSNotificationCenter defaultCenter] addObserver:self  
  48.                                                      selector:@selector(clearMemory)  
  49.                                                          name:UIApplicationDidEnterBackgroundNotification  
  50.                                                        object:nil];  
  51.         }  
  52. #endif  
  53. #endif  
  54.     }  
  55.       
  56.     return self;  
  57. }  
  58.   
  59. - (void)dealloc  
  60. {  
  61.     [memCache release], memCache = nil;  
  62.     [diskCachePath release], diskCachePath = nil;  
  63.     [cacheInQueue release], cacheInQueue = nil;  
  64.       
  65.     [[NSNotificationCenter defaultCenter] removeObserver:self];  
  66.       
  67.     [super dealloc];  
  68. }  
  69.   
  70. #pragma mark SDImageCache (class methods)  
  71.   
  72. + (SDImageCache *)sharedImageCache  
  73. {  
  74.     if (instance == nil)  
  75.     {  
  76.         instance = [[SDImageCache alloc] init];  
  77.     }  
  78.       
  79.     return instance;  
  80. }  
  81.   
  82. #pragma mark SDImageCache (private)  
  83.   
  84. /*  
  85.  *创建指定图片key的路径  
  86.  */  
  87. - (NSString *)cachePathForKey:(NSString *)key  
  88. {  
  89.     const char *str = [key UTF8String];  
  90.     unsigned char r[CC_MD5_DIGEST_LENGTH];  
  91.     CC_MD5(str, (CC_LONG)strlen(str), r);  
  92.     NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",  
  93.                           r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]];  
  94.       
  95.     return [diskCachePath stringByAppendingPathComponent:filename];  
  96. }  
  97.   
  98. /*  
  99.  *保存key和Data到物理存储  
  100.  *keyAndData[0] ->key  
  101.  *keyAndData[1] ->Data  
  102.  */  
  103. - (void)storeKeyWithDataToDisk:(NSArray *)keyAndData  
  104. {  
  105.     // Can't use defaultManager another thread  
  106.     NSFileManager *fileManager = [[NSFileManager alloc] init];  
  107.       
  108.     NSString *key = [keyAndData objectAtIndex:0];  
  109.     NSData *data = [keyAndData count] > 1 ? [keyAndData objectAtIndex:1] : nil;  
  110.       
  111.     //如果有数据,则保存到物理存储上  
  112.     if (data)  
  113.     {  
  114.         [fileManager createFileAtPath:[self cachePathForKey:key] contents:data attributes:nil];  
  115.     }  
  116.     else  
  117.     {  
  118.         //如果没有data,则把UIImage转换为JPEG,并保存到物理存储上  
  119.         // If no data representation given, convert the UIImage in JPEG and store it  
  120.         // This trick is more CPU/memory intensive and doesn't preserve alpha channel  
  121.         UIImage *image = [[self imageFromKey:key fromDisk:YES] retain]; // be thread safe with no lock  
  122.         if (image)  
  123.         {  
  124. #if TARGET_OS_IPHONE  
  125.             [fileManager createFileAtPath:[self cachePathForKey:key] contents:UIImageJPEGRepresentation(image, (CGFloat)1.0) attributes:nil];  
  126. #else  
  127.             NSArray*  representations  = [image representations];  
  128.             NSData* jpegData = [NSBitmapImageRep representationOfImageRepsInArray: representations usingType: NSJPEGFileType properties:nil];  
  129.             [fileManager createFileAtPath:[self cachePathForKey:key] contents:jpegData attributes:nil];  
  130. #endif  
  131.             [image release];  
  132.         }  
  133.     }  
  134.       
  135.     [fileManager release];  
  136. }  
  137.   
  138. /*  
  139.  *查找图片委托  
  140.  */  
  141. - (void)notifyDelegate:(NSDictionary *)arguments  
  142. {  
  143.     NSString *key = [arguments objectForKey:@"key"];  
  144.     id <SDImageCacheDelegate> delegate = [arguments objectForKey:@"delegate"];  
  145.     NSDictionary *info = [arguments objectForKey:@"userInfo"];  
  146.     UIImage *image = [arguments objectForKey:@"image"];  
  147.       
  148.     if (image)  
  149.     {  
  150.         [memCache setObject:image forKey:key];  
  151.           
  152.         if ([delegate respondsToSelector:@selector(imageCache:didFindImage:forKey:userInfo:)])  
  153.         {  
  154.             [delegate imageCache:self didFindImage:image forKey:key userInfo:info];  
  155.         }  
  156.     }  
  157.     else  
  158.     {  
  159.         if ([delegate respondsToSelector:@selector(imageCache:didNotFindImageForKey:userInfo:)])  
  160.         {  
  161.             [delegate imageCache:self didNotFindImageForKey:key userInfo:info];  
  162.         }  
  163.     }  
  164. }  
  165.   
  166. /*  
  167.  *查找物理缓存上的图片  
  168.  */  
  169. - (void)queryDiskCacheOperation:(NSDictionary *)arguments  
  170. {  
  171.     NSString *key = [arguments objectForKey:@"key"];  
  172.     NSMutableDictionary *mutableArguments = [[arguments mutableCopy] autorelease];  
  173.       
  174.     UIImage *image = [[[UIImage alloc] initWithContentsOfFile:[self cachePathForKey:key]] autorelease];  
  175.     if (image)  
  176.     {  
  177. #ifdef ENABLE_SDWEBIMAGE_DECODER  
  178.         UIImage *decodedImage = [UIImage decodedImageWithImage:image];  
  179.         if (decodedImage)  
  180.         {  
  181.             image = decodedImage;  
  182.         }  
  183. #endif  
  184.         [mutableArguments setObject:image forKey:@"image"];  
  185.     }  
  186.       
  187.     [self performSelectorOnMainThread:@selector(notifyDelegate:) withObject:mutableArguments waitUntilDone:NO];  
  188. }  
  189.   
  190. #pragma mark ImageCache  
  191.   
  192. /*  
  193.  *缓存图片  
  194.  *  
  195.  **/  
  196. - (void)storeImage:(UIImage *)image imageData:(NSData *)data forKey:(NSString *)key toDisk:(BOOL)toDisk  
  197. {  
  198.     if (!image || !key)  
  199.     {  
  200.         return;  
  201.     }  
  202.       
  203.     //缓存图片到内存上  
  204.     [memCache setObject:image forKey:key];  
  205.       
  206.     //如果需要缓存到物理存储上,并data不为空,则把data缓存到物理存储上  
  207.     if (toDisk)  
  208.     {  
  209.         if (!data) return;  
  210.         NSArray *keyWithData;  
  211.         if (data)  
  212.         {  
  213.             keyWithData = [NSArray arrayWithObjects:key, data, nil];  
  214.         }  
  215.         else  
  216.         {  
  217.             keyWithData = [NSArray arrayWithObjects:key, nil];  
  218.         }  
  219.         //后台线程缓存图片到物理存储上  
  220.         [cacheInQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self  
  221.                                                                          selector:@selector(storeKeyWithDataToDisk:)  
  222.                                                                            object:keyWithData] autorelease]];  
  223.     }  
  224. }  
  225.   
  226. /*  
  227.  *保存图片到内存上,不保存到物理存储上  
  228.  */  
  229. - (void)storeImage:(UIImage *)image forKey:(NSString *)key  
  230. {  
  231.     [self storeImage:image imageData:nil forKey:key toDisk:YES];  
  232. }  
  233. /*  
  234.  *保存图片到内存上,不保存到物理存储上  
  235.  */  
  236. - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk  
  237. {  
  238.     [self storeImage:image imageData:nil forKey:key toDisk:toDisk];  
  239. }  
  240.   
  241. /*  
  242.  *通过key返回指定图片  
  243.  */  
  244. - (UIImage *)imageFromKey:(NSString *)key  
  245. {  
  246.     return [self imageFromKey:key fromDisk:YES];  
  247. }  
  248.   
  249. /*  
  250.  *返回一张图像  
  251.  *key:图像的key  
  252.  *fromDisk:如果内存中没有图片,是否在物理存储上查找  
  253.  *return 返回查找到的图片,如果没有则返回nil  
  254.  */  
  255. - (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk  
  256. {  
  257.     if (key == nil)  
  258.     {  
  259.         return nil;  
  260.     }  
  261.       
  262.     UIImage *image = [memCache objectForKey:key];  
  263.       
  264.     if (!image && fromDisk) //如果内存没有图片,并且可以在物理存储上查找,则返回物理存储上的图片  
  265.     {  
  266.         image = [[[UIImage alloc] initWithContentsOfFile:[self cachePathForKey:key]] autorelease];  
  267.         if (image)  
  268.         {  
  269.             [memCache setObject:image forKey:key];  
  270.         }  
  271.     }  
  272.       
  273.     return image;  
  274. }  
  275.   
  276. - (void)queryDiskCacheForKey:(NSString *)key delegate:(id <SDImageCacheDelegate>)delegate userInfo:(NSDictionary *)info  
  277. {  
  278.     if (!delegate)  
  279.     {  
  280.         return;  
  281.     }  
  282.       
  283.     if (!key)  
  284.     {  
  285.         if ([delegate respondsToSelector:@selector(imageCache:didNotFindImageForKey:userInfo:)])  
  286.         {  
  287.             [delegate imageCache:self didNotFindImageForKey:key userInfo:info];  
  288.         }  
  289.         return;  
  290.     }  
  291.       
  292.     // First check the in-memory cache...  
  293.     UIImage *image = [memCache objectForKey:key];  
  294.     if (image)  
  295.     {  
  296.         // ...notify delegate immediately, no need to go async  
  297.         if ([delegate respondsToSelector:@selector(imageCache:didFindImage:forKey:userInfo:)])  
  298.         {  
  299.             [delegate imageCache:self didFindImage:image forKey:key userInfo:info];  
  300.         }  
  301.         return;  
  302.     }  
  303.       
  304.     NSMutableDictionary *arguments = [NSMutableDictionary dictionaryWithCapacity:3];  
  305.     [arguments setObject:key forKey:@"key"];  
  306.     [arguments setObject:delegate forKey:@"delegate"];  
  307.     if (info)  
  308.     {  
  309.         [arguments setObject:info forKey:@"userInfo"];  
  310.     }  
  311.     [cacheOutQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(queryDiskCacheOperation:) object:arguments] autorelease]];  
  312. }  
  313.   
  314. /*  
  315.  *从内存和物理存储上移除指定图片  
  316.  */  
  317. - (void)removeImageForKey:(NSString *)key  
  318. {  
  319.     if (key == nil)  
  320.     {  
  321.         return;  
  322.     }  
  323.       
  324.     [memCache removeObjectForKey:key];  
  325.     [[NSFileManager defaultManager] removeItemAtPath:[self cachePathForKey:key] error:nil];  
  326. }  
  327. /*  
  328.  *清除内存缓存区的图片  
  329.  */  
  330. - (void)clearMemory  
  331. {  
  332.     [cacheInQueue cancelAllOperations]; // won't be able to complete  
  333.     [memCache removeAllObjects];  
  334. }  
  335.   
  336. /*  
  337.  *清除物理存储上的图片  
  338.  */  
  339. - (void)clearDisk  
  340. {  
  341.     [cacheInQueue cancelAllOperations];  
  342.     [[NSFileManager defaultManager] removeItemAtPath:diskCachePath error:nil];  
  343.     [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath  
  344.                               withIntermediateDirectories:YES  
  345.                                                attributes:nil  
  346.                                                     error:NULL];  
  347. }  
  348. /*  
  349.  *清除过期缓存的图片  
  350.  */  
  351. - (void)cleanDisk  
  352. {  
  353.     NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-cacheMaxCacheAge];  
  354.     NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:diskCachePath];  
  355.     for (NSString *fileName in fileEnumerator)  
  356.     {  
  357.         NSString *filePath = [diskCachePath stringByAppendingPathComponent:fileName];  
  358.         NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];  
  359.         if ([[[attrs fileModificationDate] laterDate:expirationDate] isEqualToDate:expirationDate])  
  360.         {  
  361.             [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];  
  362.         }  
  363.     }  
  364. }  
  365.   
  366. @end  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值