Création de QR Code avec logo
Pixel INC
Membre
Bonjour,
Je crée une application de création de QR Code, et j'essaie d'y intégrer une fonctionnalité qui permet de mettre une image en logo de fond, j'obtient donc ceci :
Impossible à scanner.
Donc, comment faire pour mieux encoder cette image afin de permettre son scan ?
Voici les 2 bouts de code responsable, le premier, celui du remplacement du fond blanc par une image, le second, le générateur même.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissViewControllerAnimated:YES completion:nil];
[UIView animateWithDuration:0.25 animations:^{
blur_qrOutput.alpha = 0.0;
qr_output.alpha = 0.0;
}];
UIImage* originalImage = nil;
originalImage = [info objectForKey:UIImagePickerControllerEditedImage];
if(originalImage==nil)
{
originalImage = [info objectForKey:UIImagePickerControllerOriginalImage];
}
if(originalImage==nil)
{
originalImage = [info objectForKey:UIImagePickerControllerCropRect];
}
UIImage* res_img = [self imageWithImage:originalImage scaledToSize:CGSizeMake(300,300)];
UIImage *qrTransp = [self changeWhiteColorTransparent:qr_generated];
qrTransp = [self imageWithImage:qrTransp scaledToSize:CGSizeMake(300,300)];
UIGraphicsBeginImageContext(qr_output.image.size);
[res_img drawAtPoint:CGPointMake(0,0)];
[qrTransp drawAtPoint:CGPointMake(0,0)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
qr_output.image = newImage;
[bg_img setSelectedSegmentIndex:UISegmentedControlNoSegment];
[UIView animateWithDuration:0.25 animations:^{
blur_qrOutput.alpha = 1.0;
qr_output.alpha = 1.0;
}];
}
-(void)generateCodeAndSwap:(NSString *)codeMessage withImageView:(UIImageView*)output_view
{
[UIView animateWithDuration:0.25 animations:^{
blur_qrOutput.alpha = 0.0;
qr_output.alpha = 0.0;
}];
[self.view endEditing:YES];
[tex setEnabled:NO];
[act_tim setAlpha:1.0];
[act_tim startAnimating];
CIFilter *filter = [CIFilter filterWithName:@CIQRCodeGenerator];
[filter setDefaults];
NSLog(@%@",codeMessage);
NSData *data = [codeMessage dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKey:@inputMessage];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage
fromRect:[outputImage extent]];
UIImage *image = [UIImage imageWithCGImage:cgImage
scale:1.
orientation:UIImageOrientationUp];
UIImage *resized = [self resizeImage:image
withQuality:kCGInterpolationNone
rate:5.0];
UIImage *final = [self imageWithImage:resized scaledToSize:CGSizeMake(300,300)];
output_view.contentMode = UIViewContentModeScaleAspectFill;
output_view.image = final;
qr_generated = final;
[UIView animateWithDuration:0.5 animations:^{
blur_qrOutput.alpha = 1.0;
qr_output.alpha = 1.0;
}];
CGImageRelease(cgImage);
[act_tim stopAnimating];
[act_tim setAlpha:0.0];
[tex setEnabled:YES];
[bg_img setSelectedSegmentIndex:1];
}
Merci de m'éclaircir, comment optimiser ceci ? Je recherche surtout quelqu'un ayant une bonne connaissance de l'algorithme de lecture des QR Code.
Cordialement
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Euh, un QRCode, de base c'est pas des carrés noirs, des marqueurs sur un fond blanc ?
C'est pour faciliter la lecture/constrastes
@Larme Si, tu as raison. En pratique, le mécanisme de correction d'erreurs est robuste. Aussi, on peut tricher un peu.
@Pixel INC. Va voir à quoi ressemblent les codes QR avec des images, tu verras qu'ils préservent le contraste entre les cases noires et blanches.
Ouais, mais alors comment faire ? ^^
Je pense que je dois remplacer le NOIR du code et pas le Blanc, mais la valeur responsable du masque blanc est celle ci :
Donc comment faire pour faire un masque noir total ?
En remplacant les pixels noirs par une image c'est parfait,
http://prntscr.com/3bqmen
ça se scanne facilement
Voici le code enlevant le noir pour les curieux
Faut juste pas avoir de photo avec du blanc dessus quoi...
Oui, j'ai mis un avertissement, et par sécurité si l'image possède un canal alpha il sera remplacé par du noir
Tu peux peut-être essayer de la relire par derrière. Et si tu n'y arrives pas, tu mets un warning comme quoi d'autres utilisateurs pourront avoir un soucis.
L'utilisateur choisi si il veut une image ou pas
Quand il sélectionne, le Picker s'affiche avec un avertissement :
"Be careful when you choose an image, if it is not dark enough, or have white color, your QR Code could be impossible to read"
Et tu connais un moyen de "lire" une image et vérifier si elle est trop claire et/ou a du blanc dedans ? Si tu as une méthode qui fait cela, je te bénis ^^
Non, je pensais plutôt à relire le QR Code généré.
Ok, je vais tenter de trouver un moyen de "mesurer" le taux de blanc dans l'image, si quelqu'un connais un moyen, je suis preneur ^^
Personnellement j'aurais analysé la couleur dominante de l'image. Après tu détectes le taux de blanc sur cette couleur et si c'est trop blanc, erreur. Sinon ça marche. Tu peux trouver une méthode ici. Si tu veux plus de résultats encore, tu tapes "detect dominant color uiimage" et y'a plein de trucs.
L'inconvénient aussi c'est que tu peux avoir la couleur dominante rouge par exemple, et que pile sur un de tes carrés, tu as un carré blanc. Du coup ton QR code ne marche plus. Pour remédier à cela tu peux aussi créer un léger masque noir sur l'image.
C'est comme ça que j'aurais fait.
je sais pas si cette méthode prendra des images alpha, je ferais des test, j'implémenterais un petit "pipeline" de test :
Arrivé de l'image => Test => Si couleur dominante trop proche du blanc => Test encore avec un masque alpha => Si encore positif => Avertissement
Mais ce que je dois détecter aussi c'est si la couleur qu'il me donne est trop proche du blanc, comment faire avec les coordonnées RGB ?
Tu sais qu'avec les couleurs RGB, (255, 255, 255) c'est du blanc. Donc après faut faire des tests du genre :
Si R > 200 && G > 200 && B > 200
Alors tu affiches un avertissement.
Le problème n'est pas la couleur mais le contraste. L'ajout d'image en arrière plan ne respecte pas la norme QR Code.
De même, plus il y a de données encodées dans le QR Code et plus la tailles des carrés réduit et donc plus c'est délicat pour le lecteur embarqué.
A défaut d'une solution parfaite, il serait plus fiable d'appliquer une image blanche semi-opaque systématiquement. Après tout dépend de la robustesse de l'algo de lecture de QRCode employé par l'utilisateur.
La norme est plutôt d'embarquer les logos dans les QR Code à la manière d'une zone morte qui n'est pas interprétée...
http://www.qrcode-monkey.com