Watch how to download trading robots for free
Find us on Telegram!
Join our fan page
Interesting script?
So post a link to it -
let others appraise it
You liked the script? Try it in the MetaTrader 5 terminal
Libraries

PNG - library for MetaTrader 5

Zorro, Nikolai Semko
Published by:
Nikolai Semko
Views:
3944
Rating:
(5)
Published:
2023.07.15 07:24
Updated:
2023.09.17 18:28
\MQL5\Include\Canvas\
Png.mqh (37.19 KB) view
iCanvas_CB.mqh (57.71 KB) view
\MQL5\Experts\ \MQL5\Files\
cubes.png (221.61 KB)
\MQL5\Images\
icons.png (210.86 KB)
Need a robot or indicator based on this code? Order it on Freelance Go to Freelance

This library allows you to comfortably work with PNG graphic files, as well as scale them.

There are two ways to upload PNG images:

  • via file
  • via a resource that is inside your ex5 file

Working with PNG images via resource:

// Constructor
// CPng(const uchar &bin_data[], bool create_canvas = false, int x = 0, int y = 0); // // Get PNG from resource
#include <Canvas\png.mqh>

#resource "//Images//icons.png" as uchar png_data[]
#resource "//Images//image1.png" as uchar image1[]

CPng png1(png_data);             // Get the PNG (icons.png) from the resource, unpack it into a bitmap array png1.bmp[], and don't create the canvas yet
CPng png2(image1, true, 200,50); // Get the PNG (image1.png) from the resource, unpack it into a bitmap array png2.bmp[], create a canvas and display it on the screen at coordinates (X=200, Y=50)


Working with PNG images via file:

// Constructor
// CPng(string file_path, bool create_canvas = false, int x = 0, int y = 0); // Get PNG from file
#include <Canvas\png.mqh>

CPng png1("image1.png");               // Get PNG image from a file (MQL5\Files\image1.png)  unpack it into a bitmap array png1.bmp[], and don't create the canvas yet
CPng png2("cubes.png",true, 200, 100); // Get PNG image from a file (MQL5\Files\cubes.png) , create a canvas and display it on the screen at coordinates (X=200, Y=100)


As you can see, it is possible to immediately form a canvas and display the image on the screen. And you can also be satisfied with just creating a bmp[] bitmap array without creating a canvas object for this image. In this case, you can use this array in more advanced implementations with your own canvases (see the demo below).

Further, an important function of this CPng class is the ability to generate a new image size using the Resize(double NewWidth) method, which will be located in the _bmp[] array, which can also be displayed on the screen, forming a canvas of this size.

In this case, the class instance will contain two bmp[] arrays (original image) with width "width" and height "height", as well as a resized _bmp[] array (width "_width" and height "_height"). All methods and parameters in the CPng class with an underscore at the beginning of the name refer to the resized image (_bmp[], _width, _height, _CreateCanvas(), _MoveCanvas())

The following functions are also available for working with original and modified images:

   void              Resize(double NewWidth);  		       // Resize Image
   bool              CreateCanvas(const int x, const int y);   // Creating canvas for bpm[] array (original size)
   bool              _CreateCanvas(const int x, const int y);  // Creating a canvas for the _bpm[] array (resized)
   bool              MoveCanvas(const int x,const int y);      // Move image canvas to original size
   bool              _MoveCanvas(const int x,const int y);     // Moving the resized image canvas
   void              BmpArrayFree() {ArrayFree(bmp);}          // Clear the main bitmap array to save memory if it is no longer needed


I have prepared a demo program-expert (Expert_Test_PNG.mq5), which compactly and visually demonstrates the work of this library. In this example, in addition to simply displaying PNG images, parsing of a table of PNG icons is implemented. (see gif animation)

I saw the implementation of this algorithm for decompressing PNG files from @Zorro in this post 7 years ago, which was taken as the basis of this library. The resize algorithm is my development.


#include <Canvas\png.mqh>
#include <Canvas\iCanvas_CB.mqh> // https://www.mql5.com/ru/code/22164
#resource "//Images//icons.png" as uchar png_data[]
//+------------------------------------------------------------------+
CPng png1(png_data);                   // Get the PNG from the resource, unpack it into a bitmap array bmp[] and don't create the canvas yet
CPng png2("cubes.png",true, 0, 100); // Get PNG from a file, create a canvas and display it on the screen at coordinates (X=0, Y=100)
//+------------------------------------------------------------------+
int OnInit() {
   png1.Resize(600);
   png1._CreateCanvas(700,150);
   png1.Resize(W.Width/6);
   png2.Resize(220);
   png2._CreateCanvas(W.MouseX, W.MouseY);


   png1.BmpArrayFree();
   EventSetMillisecondTimer(30);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
   EventKillTimer();
}
//+------------------------------------------------------------------+
void OnTick() {
}
//+------------------------------------------------------------------+
void OnTimer() {
   static double angle = 0;
   DrawIcons(angle);
   angle+=0.06;
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   if (id == CHARTEVENT_MOUSE_MOVE) {
      png2._MoveCanvas(W.MouseX, W.MouseY);
      png2.MoveCanvas(W.MouseX/10, 100+W.MouseY/10);
      png1._MoveCanvas(700+W.MouseX/16, 150+W.MouseY/16);
   }
}
//+------------------------------------------------------------------+
void DrawIcons (double angle) {
   Canvas.Erase(0);
   double dx = png1._width/8.0;
   double dy = png1._height/6.0;
   for (int x = 0; x<8; x++)
      for (int y = 0; y<6; y++) {
         int i = y*8+x;
         int X = (i+1)*W.Width/50;
         int Y = 60+Round(sin(angle+X*20.0/W.Width)*50);
         int adr = int(y*dy)*png1._width + int(x*dx);
         for (int h = 0; h<dy; h++) ArrayCopy(Canvas.m_pixels,png1._bmp,(Y+h)*W.Width+X,adr+h*png1._width,int(dx));
      }
   Canvas.Update();
}
//+------------------------------------------------------------------+



    Dynamic Support and Resistance Dynamic Support and Resistance

    The "Dynamic Support and Resistance" Indicator is a versatile tool that combines support and resistance levels with real-time market dynamics. By incorporating previous daily highs and lows, it provides valuable insights into market psychology and identifies potential areas of price reversals or breakouts. With its ability to adapt to changing market conditions and customizable options, traders can stay ahead of trends and make informed decisions. This indicator is suitable for various trading styles and timeframes, empowering both experienced and novice traders with a competitive edge.

    New Concept: Trailing Take Profit New Concept: Trailing Take Profit

    On contrast with Trailing Stop which a stop loss trails price until the price hits the stop loss and the position gets closed in profit, introducing Trailing Take Profit which take profit trails price when a position is in loss and ultimately the position gets closed with loss.

    Grid, MartinGale include File Grid, MartinGale include File

    Enables Programmers to create Martin Gale and Grid Trading strategies with ease.

    Support and Resistance indicator for MQL5 Support and Resistance indicator for MQL5

    This is a custom support and resistance indicator, signaling bouncebacks and key market levels.