1
votes

In an app that I'm making I need to write text over a WriteableBitmap. In Windows Phone Silverlight I know how to do it: I only need to call writeableBitmap.Render() method, that's all! The problema is that my app needs to be built with Windows Runtime, and that method doesn't exist. My first approach was to write a method that performs drawing of numbers (I only need to draw numbers) over the WriteableBitmap, but, with this method, numbers appear a Little "robotic", they are all square and they definitely don't look really nice. So, is there any solution to accomplish what I want? I mean: could you help me finishing my method to draw nice-looking numbers? or... do you know any way to covert font symbols into png, and then call writeableBitmap.Blit() and then resize that font element (each number) accordingly?

Thanks in advance.

My code is as follows:

private void DrawStringAsLines(string text, WriteableBitmap writBmp, int startX, int startY)
    {
        int x = startX;
        int y = startY;
        //int radius = 1;
        int size = 2;
        int rectangleHeight = writBmp.PixelHeight / 40;
        int rectangleWidth = writBmp.PixelWidth / 40;

        int whiteSpaceSize = rectangleWidth / 2;

        x -= ((rectangleWidth + whiteSpaceSize) * text.Length);
        y -= (rectangleHeight + whiteSpaceSize + size);

        foreach (char c in text)
        {
            switch (c)
            {
                case '0':
                    {
                        /*writBmp.DrawLine(10, 20, 50, 20, Colors.White);
                        writBmp.DrawLine(10, 20, 10, 70, Colors.White);
                        writBmp.DrawLine(10, 70, 50, 70, Colors.White);
                        writBmp.DrawLine(50, 20, 50, 70, Colors.White);*/

                        /*writBmp.DrawLineAa(x, y, x + 20, y, Colors.Yellow);
                        writBmp.FillEllipseCentered(x, y, 5, 5, Colors.Yellow);
                        writBmp.DrawLineAa(x, y, x, y + 20, Colors.Yellow);
                        writBmp.FillEllipseCentered(x, y, 5, 5, Colors.Yellow);
                        writBmp.DrawLineAa(x, y + 20, x + 20, y + 20, Colors.Yellow);
                        writBmp.FillEllipseCentered(x, y + 20, 5, 5, Colors.Yellow);
                        writBmp.DrawLineAa(x + 20, y, x + 20, y + 20, Colors.Yellow);
                        writBmp.FillEllipseCentered(x + 20, y, 5, 5, Colors.Yellow);*/



                        /*writBmp.DrawLineAa(x, y, x+20, y, Colors.Yellow);


                        //for (int i = 0; i <= 20; i++ )
                         //   writBmp.FillEllipseCentered(x+i, y, radius, radius, Colors.Yellow);

                        writBmp.DrawLineAa(x, y, x, y + 20, Colors.Yellow);

                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x, y+i, radius, radius, Colors.Yellow);

                        writBmp.DrawLineAa(x, y + 20, x + 20, y + 20, Colors.Yellow);

                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x+i, y + 20, radius, radius, Colors.Yellow);

                        writBmp.DrawLineAa(x + 20, y, x + 20, y + 20, Colors.Yellow);

                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x + 20, y + i, radius, radius, Colors.Yellow);*/

                        writBmp.FillRectangle(x, y, x + rectangleWidth + size, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y, x + size, y + rectangleHeight, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth + size, y, x + rectangleWidth + size + size, y + rectangleHeight, Colors.Yellow);
                        writBmp.FillRectangle(x, y + rectangleHeight, x + rectangleWidth + size, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }

                case '1':
                    {
                        /*writBmp.DrawLineAa(x, y, x, y+20, Colors.Yellow);

                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x, y + i, radius, radius, Colors.Yellow);

                        writBmp.DrawLineAa(x, y, x - 10, y + 10, Colors.Yellow);

                        //for (int i = 0; i <= 10; i++)
                          //  writBmp.FillEllipseCentered(x - i, y + i, radius, radius, Colors.Yellow);*/
                        writBmp.FillRectangle(x, y, x + (rectangleWidth / 2) + size, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x + (rectangleWidth / 2), y, x + (rectangleWidth / 2) + size, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }
                case '2':
                    {
                        /*writBmp.DrawLineAa(x, y, x + 20, y, Colors.Yellow);
                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x + i, y, radius, radius, Colors.Yellow);

                        writBmp.DrawLineAa(x + 20, y, x + 20, y + 10, Colors.Yellow);
                        //for (int i = 0; i <= 10; i++)
                          //  writBmp.FillEllipseCentered(x + 20, y + i, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x + 20, y + 10, x, y + 10, Colors.Yellow);
                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x + i, y + 10, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x, y + 10, x, y + 20, Colors.Yellow);
                        //for (int i = 0; i <= 10; i++)
                          //  writBmp.FillEllipseCentered(x, y + 10 + i, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x, y + 20, x + 20, y + 20, Colors.Yellow);
                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x + i, y + 20, radius, radius, Colors.Yellow);*/
                        writBmp.FillRectangle(x, y, x + rectangleWidth, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y, x + rectangleWidth + size, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + size, y + rectangleHeight + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y + rectangleHeight, x + rectangleWidth + size, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }
                case '3':
                    {
                        /*writBmp.DrawLineAa(x, y, x + 20, y, Colors.Yellow);
                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x + i, y, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x + 20, y, x + 20, y + 10, Colors.Yellow);
                        //for (int i = 0; i <= 10; i++)
                          //  writBmp.FillEllipseCentered(x + 20, y + i, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x + 20, y + 10, x, y + 10, Colors.Yellow);
                        //for (int i = 0; i <= 20; i++)
                          //  writBmp.FillEllipseCentered(x + i, y + 10, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x + 20, y + 10, x + 20, y + 20, Colors.Yellow);
                        //for (int i = 0; i <= 10; i++)
                          //  writBmp.FillEllipseCentered(x + 20, y + 10 + i, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x + 20, y + 20, x, y + 20, Colors.Yellow);
                        //for (int i = 0; i <= 20; i++)
                            //writBmp.FillEllipseCentered(x + i, y + 20, radius, radius, Colors.Yellow);*/
                        writBmp.FillRectangle(x, y, x + rectangleWidth, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y, x + rectangleWidth + size, y + (rectangleHeight / 2), Colors.Yellow);
                        writBmp.FillRectangle(x + (rectangleWidth / 2), y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y + (rectangleHeight / 2), x + rectangleWidth + size, y + rectangleHeight + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y + rectangleHeight, x + rectangleWidth, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }
                case '4':
                    {
                        /*writBmp.DrawLineAa(x, y, x, y + 10, Colors.Black);
                        //for (int i = 0; i <= 10; i++)
                           // writBmp.FillEllipseCentered(x, y + i, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x, y + 10, x + 20, y + 10, Colors.Black);
                        //for (int i = 0; i <= 20; i++)
                            //writBmp.FillEllipseCentered(x + i, y + 10, radius, radius, Colors.Yellow);
                        writBmp.DrawLineAa(x + 20, y, x + 20, y + 20, Colors.Black);
                        //for (int i = 0; i <= 20; i++)
                            //writBmp.FillEllipseCentered(x + 20, y + i, radius, radius, Colors.Yellow);*/

                        writBmp.FillRectangle(x, y, x + size, y + (rectangleHeight / 2), Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y, x + rectangleWidth + size, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }
                case '5':
                    {
                        /*writBmp.DrawLine(x, y, x + 20, y, Colors.Yellow);
                        for (int i = 0; i <= 10; i++)
                            writBmp.FillEllipseCentered(x + i*2, y, radius*2, radius*2, Colors.Yellow);
                        writBmp.DrawLine(x, y, x, y + 10, Colors.Yellow);
                        for (int i = 0; i <= 5; i++)
                            writBmp.FillEllipseCentered(x, y + i*2, radius*2, 2*radius, Colors.Yellow);
                        writBmp.DrawLine(x, y + 10, x + 20, y + 10, Colors.Yellow);
                        for (int i = 0; i <= 10; i++)
                            writBmp.FillEllipseCentered(x + 2*i, y + 10, 2*radius, 2*radius, Colors.Yellow);
                        writBmp.DrawLine(x + 20, y + 10, x + 20, y + 20, Colors.Yellow);
                        for (int i = 0; i <= 5; i++)
                            writBmp.FillEllipseCentered(x + 20, y + 10 + 2*i, 2*radius, radius*2, Colors.Yellow);
                        writBmp.DrawLine(x + 20, y + 20, x, y + 20, Colors.Yellow);
                        for (int i = 0; i <= 10; i++)
                            writBmp.FillEllipseCentered(x + 2*i, y + 20, radius*2, radius*2, Colors.Yellow);*/
                        writBmp.FillRectangle(x, y, x + rectangleWidth + size, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y, x + size, y + (rectangleHeight / 2), Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y + (rectangleHeight / 2), x + rectangleWidth + size, y + rectangleHeight, Colors.Yellow);
                        writBmp.FillRectangle(x, y + rectangleHeight, x + rectangleWidth + size, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }
                case '6':
                    {
                        writBmp.FillRectangle(x, y, x + rectangleWidth, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y, x + size, y + rectangleHeight, Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y + (rectangleHeight / 2), x + rectangleWidth + size, y + rectangleHeight, Colors.Yellow);
                        writBmp.FillRectangle(x, y + rectangleHeight, x + rectangleWidth, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }
                case '7':
                    {
                        writBmp.FillRectangle(x, y, x + rectangleWidth, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y, x + rectangleWidth + size, y + rectangleHeight + size, Colors.Yellow);
                        writBmp.FillRectangle(x + (rectangleWidth / 2), y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        break;
                    }
                case '8':
                    {
                        writBmp.FillRectangle(x, y, x + rectangleWidth, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y, x + size, y + (rectangleHeight / 2), Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y, x + rectangleWidth + size, y + (rectangleHeight / 2), Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + size, y + rectangleHeight, Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y + (rectangleHeight / 2), x + rectangleWidth + size, y + rectangleHeight, Colors.Yellow);
                        writBmp.FillRectangle(x, y + rectangleHeight, x + rectangleWidth, y + rectangleHeight + size, Colors.Yellow);
                        break;
                    }
                case '9':
                    {
                        writBmp.FillRectangle(x, y, x + rectangleWidth, y + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y, x + size, y + (rectangleHeight / 2), Colors.Yellow);
                        writBmp.FillRectangle(x + rectangleWidth, y, x + rectangleWidth + size, y + rectangleHeight + size, Colors.Yellow);
                        writBmp.FillRectangle(x, y + (rectangleHeight / 2), x + rectangleWidth, y + (rectangleHeight / 2) + size, Colors.Yellow);
                        break;
                    }
                case '/':
                    {
                        writBmp.DrawLine(x + (rectangleWidth / 2), y + rectangleHeight, x + rectangleWidth, y, Colors.Yellow);
                        var increment = (rectangleWidth / 10);
                        writBmp.DrawLine(x + (rectangleWidth / 2) + increment, y + rectangleHeight, x + rectangleWidth + increment, y, Colors.Yellow);
                        increment += increment;
                        writBmp.DrawLine(x + (rectangleWidth / 2) + increment, y + rectangleHeight, x + rectangleWidth + increment, y, Colors.Yellow);

                        break;
                    }
            }

            x += (rectangleWidth + whiteSpaceSize);
        }
    }
1
How about rendering a UserControl (or just a TextBlock) to an image instead of manually "drawing" the numbers? - yasen
Do you mean using RenderTargetBitmap to render the TextBlock to an image and then calling writeableBitmap.Blit() to put the TextBlock over the image? If so, could you help me with the process? I have already done it, but numbers appear VERY big. - fergaral
I meant what @RobCaplan suggested. Make a UserControl that looks the way you want (with background image, text, whatever you need), initialize it and then use RenderTargetBitmap to create an image out of that UserControl. Basically, everything you want to be on the resulting image, should be in that UserControl, so once you render it - you would have the image that you want. Hope that helps. :) - yasen
Yes, I have already tried it. On Windows 8.1 it works just as expected, but in Windows Phone 8.1 it doesn't work. See my other question stackoverflow.com/questions/28501503/… - fergaral

1 Answers

2
votes

The analogous functionality to WriteableBitmap.Render for Windows Runtime apps is RenderTargetBitmap. The easiest way to draw text on a bitmap is to put your bitmap and a TextBlock with the text in a Grid or Canvas then call RenderTargetBitmap on the container Canvas to render the combined image + text into a new bitmap.

Other alternates are to interop with DirectWrite to draw text at the DirectX layer, or to use an external raster graphics package such as Win2D or WriteableBitmapEx (I'm not sure if WriteableBitmapEx can do text on Windows Phone).