使用 DrawString (MonoTouch) 向 UIImageView 添加文本时遇到问题

Posted

技术标签:

【中文标题】使用 DrawString (MonoTouch) 向 UIImageView 添加文本时遇到问题【英文标题】:Trouble adding text to a UIImageView using DrawString (MonoTouch) 【发布时间】:2011-02-03 21:25:24 【问题描述】:

我想使用 C# 和 MonoTouch 在 iPhone 上的图像上写入文本。 DrawImage 方法看起来很简单,但是当我运行它时会出错。我错过了什么?非常感谢任何帮助! 提前致谢。

错误:

Thu Feb  3 12:40:34 MacMini.local ImageTextMT[3877] <Error>: CGContextSetFont: invalid context 0x0  
Thu Feb  3 12:40:34 MacMini.local ImageTextMT[3877] <Error>: CGContextSetTextMatrix: invalid context 0x0  
Thu Feb  3 12:40:34 MacMini.local ImageTextMT[3877] <Error>: CGContextSetFontSize: invalid context 0x0  
Thu Feb  3 12:40:34 MacMini.local ImageTextMT[3877] <Error>: CGContextSetTextPosition: invalid context 0x0  
Thu Feb  3 12:40:34 MacMini.local ImageTextMT[3877] <Error>: CGContextShowGlyphsWithAdvances: invalid context 0x0 

MonoDevelop 2.4.2,MonoTouch

    我创建了一个新解决方案:C#、iPhone 和 iPad、基于 iPhone 窗口的项目

    编辑了 MainWindow.xib: 2a。在窗口中添加了 UIImageView 和 UIButton; 2b。我在 AppDelegate 中添加了两个出口,btnAddText(引用到 UIButton)和 imgImage(引用到 UIImageView);

    代码(抱歉——代码格式受到质疑...):

    using System;
    using System.Collections.Generic;
    using MonoTouch.Foundation;
    using MonoTouch.UIKit;
    using MonoTouch.CoreGraphics;
    using System.Drawing;
    
    namespace ImageTextMT;
    
    
    public class Application
        
            static void Main (string[] args)
            
        UIApplication.Main (args);
            
        
    
    // The name AppDelegate is referenced in the MainWindow.xib file.
        public partial class AppDelegate : UIApplicationDelegate
        
        // This method is invoked when the application has loaded its UI and its ready to run
        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
            
                // If you have defined a view, add it here:
                // window.AddSubview (navigationController.View);
            window.MakeKeyAndVisible ();
    
            // Add the events for the controls
                btnAddText.TouchDown += btnAddText_Click;
    
                imgImage.Image = UIImage.FromFile("/Users/ParisRat/Projects/ImageTextMT/ImageTextMT/images/testblock.png");
                return true;
            
    
            protected void btnAddText_Click (object sender, EventArgs e)
            
                // Define a rectangle
                System.Drawing.RectangleF rect = new System.Drawing.RectangleF(10.0f, 5.0f, 20.0f, 25.0f);
    
                // *** Write text on to the image ***
                this.imgImage.DrawString("HELLO",rect,UIFont.SystemFontOfSize(15.0f), UILineBreakMode.CharacterWrap, UITextAlignment.Left);
            
    
    
            // This method is required in iPhoneOS 3.0
            public override void OnActivated (UIApplication application)
            
            
        
        
    

【问题讨论】:

您是否仔细检查了您的矩形大小?也许它从图像中提取而你看不到它。 【参考方案1】:

你有两个选择。如果你想使用 imgImage.DrawString 方法,你需要先继承 ImageView,重写 Draw 方法并在那里调用 imgImage.DrawString 方法。

第二个选项是创建您自己的位图上下文并在那里绘制。在 monotouch.dialog 中可以找到一个很好的例子。有一个自定义绘制的日历。这是那里的代码。

public static UIImage MakeCalendarBadge (UIImage template, string smallText, string bigText) 
        using (var cs = CGColorSpace.CreateDeviceRGB ())
            using (var context = new CGBitmapContext (IntPtr.Zero, 57, 57, 8, 57*4, cs, CGImageAlphaInfo.PremultipliedLast))
                //context.ScaleCTM (0.5f, -1);
                context.TranslateCTM (0, 0);
                context.DrawImage (new RectangleF (0, 0, 57, 57), template.CGImage);
                context.SetRGBFillColor (1, 1, 1, 1);

                context.SelectFont ("Helvetica", 10f, CGTextEncoding.MacRoman);

                // Pretty lame way of measuring strings, as documented:
                var start = context.TextPosition.X;                 
                context.SetTextDrawingMode (CGTextDrawingMode.Invisible);
                context.ShowText (smallText);
                var width = context.TextPosition.X - start;

                var ns = new NSString (smallText);
                UIFont ff = UIFont.FromName ("Helvetica", 10);

                context.SetTextDrawingMode (CGTextDrawingMode.Fill);
                context.ShowTextAtPoint ((57-width)/2, 46, smallText);

                // The big string
                context.SelectFont ("Helvetica-Bold", 32, CGTextEncoding.MacRoman);                 
                start = context.TextPosition.X;
                context.SetTextDrawingMode (CGTextDrawingMode.Invisible);
                context.ShowText (bigText);
                width = context.TextPosition.X - start;

                context.SetRGBFillColor (0, 0, 0, 1);
                context.SetTextDrawingMode (CGTextDrawingMode.Fill);
                context.ShowTextAtPoint ((57-width)/2, 9, bigText);

                context.StrokePath ();

                return UIImage.FromImage (context.ToImage ());
            
        
    

【讨论】:

就 UIImageView 而言,只有您的第二个选项适用。覆盖 UIImageView 中的 Draw 方法将不起作用,因为它永远不会被调用,因为唯一可用的图形上下文是私有的,用于绘制视图的图像。也就是说,例如,在 UIImageView 上调用 SetNeedsDisplay() 什么都不做。

以上是关于使用 DrawString (MonoTouch) 向 UIImageView 添加文本时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 DrawString 将单个字符居中

如何对齐 SpriteBatch.DrawString 绘制的文本?

drawString 方法如何用于编写对角线方式

Graphics.DrawString 指定文本的不透明度

如何使用 PDFBox drawString 插入换行符

使用Java drawString实现如下Text对齐