Ich möchte programmgesteuert ein Bild wie dieses erstellen:
Ich habe das obere Bild und den Text bei mir. Soll ich Text auf das Bild schreiben?
Ich möchte daraus ein vollständiges PNG-Bild (Bild + Beschriftung) machen und es als Hintergrund für die Schaltfläche festlegen.
ios
iphone
uiimageview
Sanchit Paurush
quelle
quelle
Antworten:
Zeichnen Sie Text in ein Bild und geben Sie das resultierende Bild zurück:
+(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; }
Verwendung:
// note: replace "ImageUtils" with the class where you pasted the method above UIImage *img = [ImageUtils drawText:@"Some text" inImage:img atPoint:CGPointMake(0, 0)];
Ändern Sie den Ursprung des Textes im Bild von 0,0 auf einen beliebigen Punkt.
Fügen Sie vor der Zeile Folgendes hinzu, um ein einfarbiges Rechteck hinter dem Text zu malen
[[UIColor whiteColor] set];
:[[UIColor brownColor] set]; CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, (image.size.height-[text sizeWithFont:font].height), image.size.width, image.size.height));
Ich verwende die Textgröße, um den Ursprung für das einfarbige Rechteck zu berechnen, aber Sie können es durch eine beliebige Zahl ersetzen.
quelle
Mein Beitrag zur ersten Antwort mit iOS 7-Unterstützung:
+(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; }
Hoffe das hilft
EDIT: geändert die
UIGraphicsBeginImageContextWithOptions
Bildschirmskala wurde . Thk @SoftDesignerquelle
UIGraphicsBeginImageContextWithOptions(image.size, YES, 0.0f);
Hier ist die Swift-Version.
func textToImage(drawText: NSString, inImage: UIImage, atPoint:CGPoint)->UIImage{ // Setup the font specific variables var textColor: UIColor = UIColor.whiteColor() var textFont: UIFont = UIFont(name: "Helvetica Bold", size: 12)! //Setup the image context using the passed image. UIGraphicsBeginImageContext(inImage.size) //Setups up the font attributes that will be later used to dictate how the text should be drawn let textFontAttributes = [ NSFontAttributeName: textFont, NSForegroundColorAttributeName: textColor, ] //Put the image into a rectangle as large as the original image. inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height)) // Creating a point within the space that is as bit as the image. var rect: CGRect = CGRectMake(atPoint.x, atPoint.y, inImage.size.width, inImage.size.height) //Now Draw the text into an image. drawText.drawInRect(rect, withAttributes: textFontAttributes) // Create a new image out of the images we have created var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() // End the context now that we have the image we need UIGraphicsEndImageContext() //And pass it back up to the caller. return newImage }
Um es zu nennen, geben Sie einfach ein Bild ein.
textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))
Die folgenden Links haben mir geholfen, dies klar zu machen.
Swift - Zeichnen von Text mit drawInRect: withAttributes:
Wie schreibe ich Text auf ein Bild in Objective-C (iOS)?
Das ursprüngliche Ziel war es, ein dynamisches Bild zu erstellen, das ich in einer AnnotaionView verwenden konnte, z. B. einen Preis an einem bestimmten Ort auf einer Karte zu setzen, und das hat sich hervorragend bewährt. Hoffe, das hilft jemandem, der versucht, das Gleiche zu tun.
quelle
Nur iOS7.
Wasserzeichen in der unteren rechten Ecke.
@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
Verwendung:
UIImage *image = [UIImage imageNamed:@"mona_lisa"]; image = [image drawWatermarkText:@"Leonardo da Vinci"];
quelle
Ich habe so etwas gemacht! Nach dem Durchsuchen und Kombinieren einiger Beispiele.
Fügt den Text in die Mitte des Bildes ein und ändert bei Bedarf die Schriftgröße.
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();
quelle
Ich habe eine vollständig angepasste Erweiterung für UIImage erstellt, um Wasserzeichen in Swift zu zeichnen:
extension UIImage{ enum WaterMarkCorner{ case TopLeft case TopRight case BottomLeft case BottomRight } func waterMarkedImage(#waterMarkText:String, corner:WaterMarkCorner = .BottomRight, margin:CGPoint = CGPoint(x: 20, y: 20), waterMarkTextColor:UIColor = UIColor.whiteColor(), waterMarkTextFont:UIFont = UIFont.systemFontOfSize(20), backgroundColor:UIColor = UIColor.clearColor()) -> UIImage{ let textAttributes = [NSForegroundColorAttributeName:waterMarkTextColor, NSFontAttributeName:waterMarkTextFont] let textSize = NSString(string: waterMarkText).sizeWithAttributes(textAttributes) var textFrame = CGRectMake(0, 0, textSize.width, textSize.height) let imageSize = self.size switch corner{ case .TopLeft: textFrame.origin = margin case .TopRight: textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y) case .BottomLeft: textFrame.origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y) case .BottomRight: textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y) } /// Start creating the image with water mark UIGraphicsBeginImageContext(imageSize) self.drawInRect(CGRectMake(0, 0, imageSize.width, imageSize.height)) NSString(string: waterMarkText).drawInRect(textFrame, withAttributes: textAttributes) let waterMarkedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return waterMarkedImage } }
Wie Sie sehen, habe ich einige Standardwerte für Attribute hinzugefügt, damit Sie diese ignorieren können, wenn Sie keine Änderungen vornehmen müssen. Hier einige Beispiele für die Verwendung:
let watermark1 = image.waterMarkedImage(waterMarkText: "@yourapp") let watermark2 = image.waterMarkedImage(waterMarkText: "your app name", corner: .TopRight, margin: CGPoint(x: 5, y: 5), waterMarkTextColor: UIColor.greenColor()) let watermark3 = image.waterMarkedImage(waterMarkText: "appName", waterMarkTextColor: UIColor.blackColor(), waterMarkTextFont: UIFont(name: "Helvatica", size: 25)!)
Swift 4.0 Version:
extension UIImage { enum WaterMarkCorner { case TopLeft case TopRight case BottomLeft case BottomRight } func waterMarkedImage(text:String, corner:WaterMarkCorner = .BottomRight, margin:CGPoint = CGPoint(x: 20, y: 20), color:UIColor = UIColor.white, font:UIFont = UIFont.systemFont(ofSize: 20), background:UIColor = UIColor.clear) -> UIImage? { let attributes = [NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.font:font] let textSize = NSString(string: text).size(withAttributes: attributes) var frame = CGRect(x: 0, y: 0, width: textSize.width, height: textSize.height) let imageSize = self.size switch corner { case .TopLeft: frame.origin = margin case .TopRight: frame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y) case .BottomLeft: frame.origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y) case .BottomRight: frame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y) } // Start creating the image with water mark UIGraphicsBeginImageContext(imageSize) self.draw(in: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height)) NSString(string: text).draw(in: frame, withAttributes: attributes) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } }
quelle
Hier ist eine Swift-Version, die den Text korrekt auf dem Bild zentriert. Dies funktioniert mit Text in verschiedenen Größen.
func addTextToImage(text: NSString, inImage: UIImage, atPoint:CGPoint) -> UIImage{ // Setup the font specific variables let textColor = YOURCOLOR let textFont = YOUR SIZE //Setups up the font attributes that will be later used to dictate how the text should be drawn let textFontAttributes = [ NSFontAttributeName: textFont, NSForegroundColorAttributeName: textColor, ] // Create bitmap based graphics context UIGraphicsBeginImageContextWithOptions(inImage.size, false, 0.0) //Put the image into a rectangle as large as the original image. inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height)) // Our drawing bounds let drawingBounds = CGRectMake(0.0, 0.0, inImage.size.width, inImage.size.height) let textSize = text.sizeWithAttributes([NSFontAttributeName:textFont]) let textRect = CGRectMake(drawingBounds.size.width/2 - textSize.width/2, drawingBounds.size.height/2 - textSize.height/2, textSize.width, textSize.height) text.drawInRect(textRect, withAttributes: textFontAttributes) // Get the image from the graphics context let newImag = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImag }
quelle
Verwenden Sie diese Methode, um Ihr Textfeld mit der ausgewählten Schriftart sowie Farbe und Größe zum Bild hinzuzufügen
//Method to add - (UIImage *) addText:(UIImage *)img text:(NSString *)text { CGRect rect = CGRectMake(0,0, img.size.width, img.size.height); // create a context according to image size UIGraphicsBeginImageContext(rect.size); // draw image [img drawInRect:rect]; float fontSize = _txtvwEdit.font.pointSize*2; NSLog(@"Original %f new %f",_txtvwEdit.font.pointSize,fontSize); UIFont* font = [UIFont fontWithName:_txtvwEdit.font.fontName size:fontSize]; CGRect textRect = CGRectMake((_txtvwEdit.frame.origin.x*2)-5,_txtvwEdit.frame.origin.y*2,_txtvwEdit.frame.size.width*2,_txtvwEdit.frame.size.height*2); if ([temparyGifframes count]>0) { font = [UIFont fontWithName:_txtvwEdit.font.fontName size:_txtvwEdit.font.pointSize]; textRect = CGRectMake(_txtvwEdit.frame.origin.x,_txtvwEdit.frame.origin.y ,_txtvwEdit.frame.size.width,_txtvwEdit.frame.size.height); } /// Make a copy of the default paragraph style NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping; paragraphStyle.alignment = NSTextAlignmentLeft; NSDictionary *attributes = @{ NSFontAttributeName: font, NSForegroundColorAttributeName: _txtvwEdit.textColor,NSParagraphStyleAttributeName: paragraphStyle }; // draw text [text drawInRect:textRect withAttributes:attributes]; // get as image UIImage * image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
quelle
In Swift-3 von @Jano Antwort: -
func drawText(text:NSString ,image:UIImage ,point:CGPoint ) -> UIImage { let font = UIFont.boldSystemFont(ofSize: 12) UIGraphicsBeginImageContext(image.size) image.draw(in:CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) ) let rect = CGRect(x: point.x, y: point.y, width:image.size.width, height: image.size.height ) UIColor.white.set() text.draw(in: rect.integral, withAttributes: [NSFontAttributeName : font]) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image! }
quelle
Swift 3
extension UIImage { func textToImage(drawText: NSString, atPoint:CGPoint) -> UIImage? { // Setup the font specific variables let textColor: UIColor = UIColor.white let textFont: UIFont = UIFont(name: "Helvetica Bold", size: 12)! //Setup the image context using the passed image. UIGraphicsBeginImageContext(self.size) //Setups up the font attributes that will be later used to dictate how the text should be drawn let textFontAttributes = [ NSFontAttributeName: textFont, NSForegroundColorAttributeName: textColor, ] as [String : Any] //Put the image into a rectangle as large as the original image. self.draw(in: CGRect(x:0, y:0, width:self.size.width, height: self.size.height)) // Creating a point within the space that is as bit as the image. let rect: CGRect = CGRect(x:atPoint.x, y:atPoint.y, width:self.size.width, height:self.size.height) //Now Draw the text into an image. drawText.draw(in: rect, withAttributes: textFontAttributes) // Create a new image out of the images we have created let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext() // End the context now that we have the image we need UIGraphicsEndImageContext() //And pass it back up to the caller. return newImage } }
quelle
Swift 3-Version von @Hossam Ghareebs antwortete und fügte die fehlende Integration des backgroundColor-Parameters hinzu:
enum WaterMarkCorner{ case TopLeft case TopRight case BottomLeft case BottomRight } extension UIImage{ func waterMarkedImage(_ waterMarkText:String, corner:WaterMarkCorner = .TopRight, margin:CGPoint = CGPoint(x: 20, y: 20), waterMarkTextColor:UIColor = UIColor.black, waterMarkTextFont:UIFont = UIFont.systemFont(ofSize: 40), backgroundColor:UIColor = UIColor(white: 1.0, alpha: 0.5)) -> UIImage?{ let textAttributes = [NSForegroundColorAttributeName:waterMarkTextColor, NSFontAttributeName:waterMarkTextFont, NSBackgroundColorAttributeName: backgroundColor] let textSize = NSString(string: waterMarkText).size(attributes: textAttributes) var textFrame = CGRect(x:0, y:0, width:textSize.width, height:textSize.height) let imageSize = self.size switch corner{ case .TopLeft: textFrame.origin = margin case .TopRight: textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y) case .BottomLeft: textFrame.origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y) case .BottomRight: textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y) } /// Start creating the image with water mark UIGraphicsBeginImageContext(imageSize) self.draw(in: CGRect(x:0, y:0, width:imageSize.width, height:imageSize.height)) NSString(string: waterMarkText).draw(in: textFrame, withAttributes: textAttributes) let waterMarkedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return waterMarkedImage } }
quelle
Meine Funktion kann Text-Wasserzeichen mit einer Drehung von 45 Grad und 90 Grad zum Bild hinzufügen
+(UIImage *)drawText:(NSString *)text diagonallyOnImage:(UIImage *)image rotation:(WatermarkRotation)rotation{ UIColor *textColor = [UIColor colorWithRed:255 green:0 blue:0 alpha:0.2];//[UIColor colorWithWhite:0.5 alpha:1.0]; UIFont *font = [UIFont systemFontOfSize:250]; // Compute rect to draw the text inside NSDictionary *attr = @{NSForegroundColorAttributeName: textColor, NSFontAttributeName: font}; CGSize textSize = [text sizeWithAttributes:attr]; CGSize imageSize = image.size; // Create a bitmap context into which the text will be rendered. UIGraphicsBeginImageContext(textSize); // Render the text [text drawAtPoint:CGPointMake(0,0) withAttributes:attr]; // Retrieve the image UIImage* img = UIGraphicsGetImageFromCurrentImageContext(); CGImageRef imageRef = [img CGImage]; CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef); CGContextRef bitmap = CGBitmapContextCreate(NULL, textSize.width, textSize.width, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo); switch (rotation) { case WatermarkRotation90left: CGContextRotateCTM (bitmap, DEGREES_RADIANS(-90)); CGContextTranslateCTM(bitmap, -textSize.width, 0); break; case WatermarkRotation90right: CGContextRotateCTM (bitmap, DEGREES_RADIANS(90)); CGContextTranslateCTM(bitmap, 0, -textSize.width); break; case WatermarkRotation45ltr: CGContextRotateCTM (bitmap, DEGREES_RADIANS(45)); CGContextTranslateCTM(bitmap, textSize.width/4, -textSize.width/2); break; case WatermarkRotation45rtl: CGContextRotateCTM (bitmap, DEGREES_RADIANS(-45)); CGContextTranslateCTM(bitmap, -textSize.width/2, textSize.width/4); break; default: break; } CGContextDrawImage(bitmap, CGRectMake(0, (textSize.width/2)-(textSize.height/2), textSize.width, textSize.height), imageRef); CGImageRef ref = CGBitmapContextCreateImage(bitmap); UIImage* newImage = [UIImage imageWithCGImage:ref]; UIGraphicsBeginImageContext( imageSize ); // Use existing opacity as is [image drawInRect:CGRectMake(0,0,imageSize.width,imageSize.height)]; if (rotation == WatermarkRotation90left) { [newImage drawInRect:CGRectMake(-((textSize.width/2)-(textSize.height/2)),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0]; }else if(rotation == WatermarkRotation90right){ [newImage drawInRect:CGRectMake((imageSize.width-textSize.width/2)-(textSize.height/2),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0]; }else{ [newImage drawInRect:CGRectMake((imageSize.width/2)-(textSize.width/2),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0]; } UIImage *mergedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return mergedImage; }
Aufzählung zur Rotation:
typedef enum:NSUInteger{ WatermarkRotation90left=1, WatermarkRotation90right, WatermarkRotation45ltr, WatermarkRotation45rtl }WatermarkRotation;
Hinweis: Verwenden Sie 0 zum Zeichnen eines Wasserzeichens in der Bildmitte (Standardfall der switch-Anweisung).
Fügen Sie dieses Makro für Grad zum Bogenmaß hinzu:
#define DEGREES_RADIANS(angle) ((angle) / 180.0 * M_PI)
Hoffe das hilft !!!
quelle
In Anbetracht der Leistung sollten Sie häufige Anrufe bei vermeiden
-drawRect:
. JedesUIView
wird mit einemCALayer
und Bildern hinterlegt , da Ebeneninhalte so lange im Speicher bleiben, wie sieCALayer
in der Hierarchie verbleiben. Dies bedeutet, dass die meisten Vorgänge, die Sie in einer Anwendung sehen, einschließlich Bewegung, Drehung und Skalierung der Ansicht / Ebene, nicht ausgeführt werden erfordern ein Redraw.Dies bedeutet, dass Sie ein Add-CATextLayer
On verwenden könnenUIImageView
, wenn Sie kein Bild mit Wasserzeichen benötigen. https://developer.apple.com/library/ios/qa/qa1708/_index.htmlCATextLayer *textLayer = [CATextLayer layer]; UIFont *font = [UIFont systemFontOfSize:14.0f]; CGSize textSize = [text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14.0f]}]; textLayer.frame = CGRectMake((imageView.size.width - textSize.width)/2, (imageView.size.height - textSize.height)/2, textSize.width, textSize.height);; textLayer.string = text; textLayer.fontSize = font.pointSize; [imageView.layer addSublayer:textLayer]; }
quelle
UIImageView *imageView = [UIImageView alloc]; imageView.image = [UIImage imageNamed:@"img.png"]; UILabel *label = [UILabel alloc]; label.text = @"Your text"; [imageView addsubview:label];
Legen Sie den Rahmen des Etiketts fest, in dem das Etikett angezeigt werden soll.
quelle