iOSはQRコードのカラー効果を実現
今日プロジェクトをするのは基本的に完成して、テストも终わりに入って、同僚は私にQRコードをカラーに変えると言って、私はもとの先辈の书いた工事の研究に対して研究に行って、多くの资料を探してやはりよくしていないで、やはりずっと失败して、そこで私の学友を探して、彼に闻いて、结局彼は出勤して私に见る时间がなくて、しかし私に脳の穴を开けて、私は突然自分があまりにも堅苦しいことを発見して、元のコードの上で必死にぶつかって、実はgithubの上で多くの書いたコードを探して私に使うことができて、しかし私は考えていないで、仕事は効率にこだわって、学習は必死に打つことができて、しかし仕事の上で必ず頭が柔軟で、八方の資源を使うことをマスターして、自分の仕事の効率を大いに高めて、教えを受けます.
今日使ったQRコードを生成して皆さんと共有します.Demoアドレス:クリックしてリンクを開く
QRCodeImage.h
QRCodeImage.m
使用方法
今日使ったQRコードを生成して皆さんと共有します.Demoアドレス:クリックしてリンクを開く
QRCodeImage.h
#import <UIKit/UIKit.h>
@interface QRCodeImage : UIImage
/**
* 1.
*
* @param string
* @param width
*
* @return <#return value description#>
*/
+ (QRCodeImage *_Nonnull)codeImageWithString:(NSString *_Nullable)string
size:(CGFloat)width;
/**
* 2.
*
* @param string
* @param width
* @param color
*
* @return <#return value description#>
*/
+ (QRCodeImage *_Nonnull)codeImageWithString:(NSString *_Nullable)string
size:(CGFloat)width
color:(UIColor *_Nullable)color;
/**
* 3.
*
* @param string
* @param width
* @param color
* @param icon
* @param iconWidth , 1/4
*
* @return <#return value description#>
*/
+ (QRCodeImage *_Nonnull)codeImageWithString:(NSString *_Nullable)string
size:(CGFloat)width
color:(UIColor *_Nullable)color
icon:(UIImage *_Nullable)icon
iconWidth:(CGFloat)iconWidth;
@end
QRCodeImage.m
#import "QRCodeImage.h"
@implementation QRCodeImage
+ (QRCodeImage *)codeImageWithString:(NSString *)string
size:(CGFloat)width
{
CIImage *ciImage = [QRCodeImage createQRForString:string];
if (ciImage) {
return [QRCodeImage createNonInterpolatedUIImageFormCIImage:ciImage
size:width];
} else {
return nil;
}
}
+ (QRCodeImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image
size:(CGFloat)size {
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent),
size/CGRectGetHeight(extent));
// 1. ,
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil,
width,
height,
8,
0,
cs,
(CGBitmapInfo)kCGImageAlphaNone);
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// 2.
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
// 3.
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return (QRCodeImage*)[UIImage imageWithCGImage:scaledImage];
}
+ (CIImage *)createQRForString:(NSString *)qrString {
// 1. UTF8 NSData
NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
// 2. filter
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 3.
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];
// 4. CIImage
return qrFilter.outputImage;
}
void ProviderReleaseData (void *info, const void *data, size_t size){
free((void*)data);
}
+ (QRCodeImage *_Nonnull)codeImageWithString:(NSString *_Nullable)string
size:(CGFloat)width
color:(UIColor *_Nullable)color;
{
QRCodeImage *image = [QRCodeImage codeImageWithString:string size:width];
const CGFloat *components = CGColorGetComponents(color.CGColor);
CGFloat red = components[0]*255;
CGFloat green = components[1]*255;
CGFloat blue = components[2]*255;
const int imageWidth = image.size.width;
const int imageHeight = image.size.height;
size_t bytesPerRow = imageWidth * 4;
uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
// 1.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rgbImageBuf,
imageWidth,
imageHeight,
8,
bytesPerRow,
colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
// 2.
int pixelNum = imageWidth * imageHeight;
uint32_t* pCurPtr = rgbImageBuf;
for (int i = 0; i < pixelNum; i++, pCurPtr++){
if ((*pCurPtr & 0xFFFFFF00) < 0x99999900){
uint8_t* ptr = (uint8_t*)pCurPtr;
ptr[3] = red; //0~255
ptr[2] = green;
ptr[1] = blue;
}else{
uint8_t* ptr = (uint8_t*)pCurPtr;
ptr[0] = 0;
}
}
// 3. UIImage
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL,
rgbImageBuf,
bytesPerRow * imageHeight,
ProviderReleaseData);
CGImageRef imageRef = CGImageCreate(imageWidth,
imageHeight,
8,
32,
bytesPerRow,
colorSpace,
kCGImageAlphaLast | kCGBitmapByteOrder32Little,
dataProvider,
NULL,
true,
kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
QRCodeImage* resultUIImage = (QRCodeImage*)[UIImage imageWithCGImage:imageRef];
// 4.
CGImageRelease(imageRef);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return resultUIImage;
}
+ (QRCodeImage *_Nonnull)codeImageWithString:(NSString *_Nullable)string
size:(CGFloat)width
color:(UIColor *_Nullable)color
icon:(UIImage *_Nullable)icon
iconWidth:(CGFloat)iconWidth
{
QRCodeImage *bgImage = [QRCodeImage codeImageWithString:string
size:width
color:color];
UIGraphicsBeginImageContext(bgImage.size);
[bgImage drawInRect:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)];
CGFloat x = (bgImage.size.width - iconWidth) * 0.5;
CGFloat y = (bgImage.size.height - iconWidth) * 0.5;
[icon drawInRect:CGRectMake( x, y, iconWidth, iconWidth)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return (QRCodeImage *)newImage;
}
@end
使用方法
QRCodeImage *qrCodeImage = [QRCodeImage codeImageWithString:@"https://github.com/EmyWong/PersonalUITech"
size:200
color:[UIColor orangeColor]
];
UIImageView *qrImageView = [[UIImageView alloc]initWithImage:qrCodeImage];
qrImageView.center = self.view.center;
[self.view addSubview:qrImageView];
self.qrImageView = qrImageView;
早くQRコードをカラーにしましょう~