0

I have to "generate" a png file and send it to the Telegram bot via SendPhotoAsync of SeendDocumentAsync.

This is a piece of my C# code:

...
Bitmap speedometer = new Bitmap(@"C:\Immagini\bot\speedometer.png");
Bitmap pointer = new Bitmap(@"C:\Immagini\bot\pointer.png");
Bitmap finalImage = new Bitmap(speedometer);
using (Graphics graphics = Graphics.FromImage(finalImage))
{
    Bitmap rotatedPointer = RotateImage(pointer, efficienza_int * (float)1.8);
    rotatedPointer.MakeTransparent(Color.White);
    graphics.SmoothingMode = SmoothingMode.HighQuality;
    graphics.DrawImage(rotatedPointer, 0, 0);
    ?????????????
}

Now, I want to send my finalImage without saving it on the disk with Save method. How can I?

Thanks in advice!

3 Answers3

4

Save it to MemoryStream, and send the MemoryStream in your call to the bot, like this:

using (MemoryStream ms = new MemoryStream())
using (Bitmap finalImage = new Bitmap(speedometer))
{
    using (Graphics graphics = Graphics.FromImage(finalImage))
    {
        // ... stuff
    }
    finalImage.Save(ms, ImageFormat.Png);
    // This is important: otherwise anything reading the stream
    // will start at the point AFTER the written image.
    ms.Position = 0;
    Bot.SendPhotoAsync(/* send 'ms' here. Whatever the exact args are */);
}

It is possible that async sending requires the stream to remain open. Though, normally, when you have such an async send, you can specify a function that should be called after the sending has finished.

In that case, you should not put the MemoryStream in a using block, but instead store the stream object in a global variable in your class, and make sure that the function handling the end of the async send disposes it.

Also do note this question...

bot.sendphoto does not work asp.net

Apparently SendPhotoAsync is not enough to actually send it; the answer there specifies you need to call .GetAwaiter() and .GetResult(). I don't know the API, so you'll have to figure that out yourself.

Nyerguds
  • 5,360
  • 1
  • 31
  • 63
0

From the Telegram Bot API documentation (link)

Sending files There are three ways to send files (photos, stickers, audio, media, etc.):

...

  1. Post the file using multipart/form-data in the usual way that files are uploaded via the browser. 10 MB max size for photos, 50 MB for other files.
Matteo
  • 2,029
  • 4
  • 22
  • 30
0

Your question is not clear! However, (if I understand your question right) You are using TelgramBotClient from this repository: https://github.com/TelegramBots

when you invoke SendPhotoAsync from this client it takes FileToSend as a parameter which represent the photo you processed with rotation, transparency and smoothing.

when you pass this FileToSend you can set the photo either by loading it from temp file you created after processing or you can load it directory from MemoryStream like this:

using System.Drawing;
using System.Drawing.Drawing2D;
using Telegram.Bot;
using Telegram.Bot.Args;
using System.IO;
using System.Drawing.Imaging;

namespace LoadGraphicsFromMemory
{
    public static class ImageExtensions
    {
        public static MemoryStream ToMemoryStream(this Bitmap image, ImageFormat format)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, format);
                return ms;
            }
        }

    }

    class Program
    {
        private static float efficienza_int;
        private static readonly TelegramBotClient Bot = new TelegramBotClient("Your API key");

        static void Main(string[] args)
        {


            Bot.OnMessage += BotOnMessageReceived;
        }

        private static void BotOnMessageReceived(object sender, MessageEventArgs e)
        {
            Bitmap speedometer = new Bitmap(@"C:\Immagini\bot\speedometer.png");
            Bitmap pointer = new Bitmap(@"C:\Immagini\bot\pointer.png");
            Bitmap finalImage = new Bitmap(speedometer);
            using (Graphics graphics = Graphics.FromImage(finalImage))
            {
                Bitmap rotatedPointer = RotateImage(pointer, efficienza_int * (float)1.8);
                rotatedPointer.MakeTransparent(Color.White);
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.DrawImage(rotatedPointer, 0, 0);

            }

            Bot.SendPhotoAsync(e.Message.Chat.Id, new Telegram.Bot.Types.FileToSend("My File", finalImage.ToMemoryStream(ImageFormat.Jpeg)));
        }

        private static Bitmap RotateImage(Bitmap pointer, object p)
        {
            return pointer;
        }


    }
}
Alaa Masalmeh
  • 57
  • 1
  • 9
  • Thanks, you've hit the point! I'm trying your solution but with the command SendPhotoAsync i'm getting and Exception: ObjectDisposedException I'm working on it. – Manuel Valente Mysteriis Mar 23 '18 at 09:33
  • This answer cannot work. You can't _return_ a stream that is created in a `using` block - the stream will be disposed and thus invalid (hence the `ObjectDisposedException`) from the moment it leaves the `ToMemoryStream` function. And don't ask people to accept an answer when they just said it doesn't work. – Nyerguds Mar 24 '18 at 16:29