78 votes

Comment écrire du texte sur une image en Objective-C (iOS) ?

Je veux créer une image comme celle-ci de manière programmatique :

example

J'ai l'image supérieure et le texte avec moi. Dois-je écrire le texte sur l'image ?

Je veux en faire une image .png complète (image + étiquette) et la définir comme arrière-plan du bouton.

0 votes

Avez-vous essayé UIImage et UILabel ?

0 votes

Non Veuillez fournir l'exemple de code pour que je puisse essayer.

0 votes

Voulez-vous simplement l'afficher comme ça dans votre application, ou voulez-vous modifier le fichier image pour qu'il contienne ce texte et le sauvegarder comme ça ?

178voto

Jano Points 37593

Dessinez du texte à l'intérieur d'une image et renvoyez l'image résultante :

+(UIImage*) drawText:(NSString*) text 
             inImage:(UIImage*)  image 
             atPoint:(CGPoint)   point 
{

    UIFont *font = [UIFont boldSystemFontOfSize:12];
    UIGraphicsBeginImageContext(image.size);
    [image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
    CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
    [[UIColor whiteColor] set];
    [text drawInRect:CGRectIntegral(rect) withFont:font]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

Utilisation :

// note: replace "ImageUtils" with the class where you pasted the method above
UIImage *img = [ImageUtils drawText:@"Some text"
                            inImage:img 
                            atPoint:CGPointMake(0, 0)];

Changez l'origine du texte à l'intérieur de l'image de 0,0 à n'importe quel point que vous souhaitez.

Pour peindre un rectangle de couleur unie derrière le texte, ajoutez ce qui suit avant la ligne [[UIColor whiteColor] set]; :

[[UIColor brownColor] set];
CGContextFillRect(UIGraphicsGetCurrentContext(), 
                  CGRectMake(0, (image.size.height-[text sizeWithFont:font].height), 
                                  image.size.width, image.size.height));

J'utilise la taille du texte pour calculer l'origine du rectangle de couleur unie, mais vous pouvez la remplacer par n'importe quel nombre.

0 votes

Oui, c'est ce dont j'avais besoin. Mais il ajoute le texte sur le côté droit de l'image. Pouvons-nous l'ajouter en bas de l'image ? S'il vous plaît aider

0 votes

Merci, mon frère. Cela fonctionne parfaitement. Une dernière chose à demander, comment définir l'arrière-plan de ce texte comme je l'ai montré dans mon exemple d'image.

0 votes

Wow, ça ressemble à ce que je voulais. Vous êtes parfait dans l'image et les graphiques de l'objectif-c. Merci encore.

35voto

iGranDav Points 1365

Ma contribution à la première réponse avec support iOS 7 :

+(UIImage*) drawText:(NSString*) text
             inImage:(UIImage*)  image
             atPoint:(CGPoint)   point
{
    UIGraphicsBeginImageContextWithOptions(image.size, YES, 0.0f);
    [image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
    CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
    [[UIColor whiteColor] set];

    UIFont *font = [UIFont boldSystemFontOfSize:12];
    if([text respondsToSelector:@selector(drawInRect:withAttributes:)])
    {
        //iOS 7
        NSDictionary *att = @{NSFontAttributeName:font};
        [text drawInRect:rect withAttributes:att];
    }
    else
    {
        //legacy support
        [text drawInRect:CGRectIntegral(rect) withFont:font];
    }

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

J'espère que cela vous aidera

EDITAR: modifié le UIGraphicsBeginImageContextWithOptions pour gérer l'échelle de l'écran. Merci à @SoftDesigner

9 votes

Merci... J'ai dû déplacer la couleur dans le dictionnaire att pour que cela fonctionne sous iOS7 : NSDictionary *att = @{ NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor whiteColor]} ;

2 votes

Remplacez la première ligne par celle-ci pour une meilleure qualité de texte : UIGraphicsBeginImageContextWithOptions(image.size, YES, 0.0f);

0 votes

Pas UIGraphicsBeginImageContext, mais UIGraphicsBeginImageContextWithOptions

18voto

neoneye Points 11545

IOS7 uniquement.

Filigrane dans le coin inférieur droit.

@interface UIImage (DrawWatermarkText)
-(UIImage*)drawWatermarkText:(NSString*)text;
@end
@implementation UIImage (DrawWatermarkText)
-(UIImage*)drawWatermarkText:(NSString*)text {
    UIColor *textColor = [UIColor colorWithWhite:0.5 alpha:1.0];
    UIFont *font = [UIFont systemFontOfSize:50];
    CGFloat paddingX = 20.f;
    CGFloat paddingY = 20.f;

    // Compute rect to draw the text inside
    CGSize imageSize = self.size;
    NSDictionary *attr = @{NSForegroundColorAttributeName: textColor, NSFontAttributeName: font};
    CGSize textSize = [text sizeWithAttributes:attr];
    CGRect textRect = CGRectMake(imageSize.width - textSize.width - paddingX, imageSize.height - textSize.height - paddingY, textSize.width, textSize.height);

    // Create the image
    UIGraphicsBeginImageContext(imageSize);
    [self drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
    [text drawInRect:CGRectIntegral(textRect) withAttributes:attr];
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultImage;
}
@end

Utilisation :

UIImage *image = [UIImage imageNamed:@"mona_lisa"];
image = [image drawWatermarkText:@"Leonardo da Vinci"];

0 votes

Utilisez UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0f) ; pour maintenir la qualité de l'image.

0 votes

@SebastianDwornik le paramètre 0.0f fait que le code dépend du fait que l'appareil soit rétina ou non.

0 votes

Correct. C'est pourquoi j'ai pris la décision de n'utiliser qu'iOS 7 et les appareils retina.

12voto

nunoines Points 81

J'ai fait quelque chose comme ça ! Après avoir parcouru et combiné quelques exemples.

Place le texte au milieu de l'image, en redimensionnant la police si nécessaire.

UIImage *myImage = [UIImage imageNamed:@"promoicon.png"];
UIGraphicsBeginImageContext(myImage.size);
[myImage drawInRect:CGRectMake(0,0,myImage.size.width,myImage.size.height)];
UITextView *myText = [[UITextView alloc] init];
myText.font = [UIFont fontWithName:@"TrebuchetMS-Bold" size:15.0f];
myText.textColor = [UIColor whiteColor];
myText.text = NSLocalizedString(@"promotionImageText", @"");
myText.backgroundColor = [UIColor clearColor];

CGSize maximumLabelSize = CGSizeMake(myImage.size.width,myImage.size.height);
CGSize expectedLabelSize = [myText.text sizeWithFont:myText.font                     
                                          constrainedToSize:maximumLabelSize 
                                              lineBreakMode:UILineBreakModeWordWrap];

myText.frame = CGRectMake((myImage.size.width / 2) - (expectedLabelSize.width / 2),
                                  (myImage.size.height / 2) - (expectedLabelSize.height / 2),
                                  myImage.size.width,
                                  myImage.size.height);

[[UIColor whiteColor] set];
[myText.text drawInRect:myText.frame withFont:myText.font];
UIImage *myNewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

0 votes

Pourquoi allouez-vous un UITextView ? Vous ne l'utilisez pas réellement, pour autant que je puisse dire -- vous n'utilisez que le cadre (un CGRect) et la police (un UIFont), qui seraient tous deux plus faciles à conserver séparément.

0 votes

...ah, à moins que ce soit l'UITextView qui redimensionne la police pour l'adapter.

-2voto

Praveen S Points 7978
UIImageView *imageView = [UIImageView alloc];
imageView.image = [UIImage imageNamed:@"img.png"];
UILabel *label = [UILabel alloc];
label.text = @"Your text";
[imageView addsubview:label];

Définissez le cadre de l'étiquette où vous voulez que l'étiquette soit affichée.

0 votes

N'oubliez pas de libérer l'étiquette après l'avoir ajoutée en tant que sous-vue.

0 votes

Je veux en faire une image complète (image + étiquette) et l'ajouter à l'arrière-plan du bouton.

0 votes

Dans ce cas, vous pouvez créer l'image et l'étiquette dans gimp/photoshop et l'utiliser comme image de fond pour un bouton.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X