ParisRat
ParisRat

Reputation: 13

Trouble adding text to a UIImageView using DrawString (MonoTouch)


I want to write text on to an image on an iPhone, using C# and MonoTouch. The DrawImage method seems pretty straight forward, but I get errors when I run it. What am I missing? Any help is greatly appreciated!
Thanks in advance.

The errors:

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

  1. I created a New Solution: C#, iPhone and iPad, iPhone Window-based Project

  2. Editted the MainWindow.xib:
    2a. Added UIImageView and UIButton to the Window;
    2b. To the AppDelegate I added two outlets, btnAddText (referenced to the UIButton) and imgImage (referenced to the UIImageView);

  3. Code (sorry-- code-formatting challenged...):

    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)
            {
            }
        }
        }
    

Upvotes: 1

Views: 2428

Answers (1)

Clancey
Clancey

Reputation: 333

You have two options. If you would like to use the imgImage.DrawString method you need to first subclass the ImageView, override the Draw method and call imgImage.DrawString method there.

Second option would be to create your own bitmap context and draw there. A good example can be find inside of monotouch.dialog. There is a custom drawn calendar. Here is the code from there.

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 ());
            }
        }
    }

Upvotes: 5

Related Questions