This is just some information, rather than a question, but I thought I'd share it since I've been wondering how to do this for some time.
The standard BITMAP and BITMAP_LABEL objects allow us to load bitmap images on to the chart, but do not support 32-bit images (with alpha channel).
This means if you want to load an image that has a transparent background, you have to first paint the background of the image the same colour as the background of your chart in a drawing program. This subsequently means if you are coding an indicator that you want to share with others, if they have a different background colour to their chart than you, it's going to show up as an ugly square of the incorrect colour.
By way of an example:
Original image with transparent background
Painted with my chart's background colour
How it looks on my chart
How it looks on someone else's chart with a white background
Not to mention that if the image ends up in front of candles even on my chart, it still looks ugly
This is where the Canvas class can come to the rescue. It had a method called LoadFromFile, which supports 32-bit bitmaps.
The syntax is simple:
canvas.CreateBitmapLabel(chartId, subwindowId, chartObjectName, x, y, width, height, COLOR_FORMAT_ARGB_RAW);
First however we must convert our bitmap to 32-bit alpha format.
There is a free program called Pixelformer which enables us to do this easily. Images can be imported in PNG format with transparency, and exported as 32-bit bitmaps. There is one small caveat - in order to display properly in MT4, the bitmap must be exported from Pixelformer with the "top-down row order" option selected. If this is not checked, only the top half of the bitmap shows up when you try to display it in MT4 (I think this is down to a bug in the section of the Canvas code which tries to flip an image when handling 32-bit format).
Once this has been done, the result can be seen as follows:
Arrow displays correctly on dark background
And against a light background
And can be superimposed in front of candles without obscuring them
If you replace the function LoadFromFile() by the fixed code, you will also be able to load images that were stored as resources. But you must not set the Top-Down-row-order flag, it won´t work.
This way you don´t need to copy the bitmaps into the files folder of any clients.
//| Load data from file |
bool CCanvas::LoadFromFile(const string filename)
//--- open file
//--- Modified by Doerk
//--- read header
Print("Failed to read file header");
//--- process depending on color depth
//--- flip image
//--- check if at least one pixel has alpha channel
//--- then leave image as is (consider it as premultiplied ARGB)
//--- there is alpha channel
//--- no alpha channel
//--- consider image as nontransparent, add alpha channel as 0xFF
//--- color components are not processed by terminal (they should be correctly specified by user)
//--- convert image to premultiplied ARGB
//--- 24 bits - change image color depth to 32 bits
//--- allocate memory for pixels
//--- the number of bytes that define a line of pixels must be multiple of 4
byte_width=m_width*3; // number of bytes in line of pixels
byte_width=(byte_width+3)&~3; // align line to the 4 byte boundary
Hallo and thank you for this publication,
I have tried the functions. The function to cerate ab BitmapLabel is running, but the image is not load.
I can see the Object in the Properties on chart and I can select it.
Now I controlled the File to the bmp and copy it for test in same Folder "Expert"
The bmp ist 32bit and I used Pixelformer and same format too.
I hope someone can help me... thank you.
I have tried the functions. The function to cerate ab BitmapLabel is running, but the image is not load...
Canvas #include is not necessary for bitmap image with alpha channel.
Bitmaps with alpha channel require #resource followed by path to image or they will not display. This is not found in MQL4 documentation but it's the only way it will work.
Example - If your image is located inside the folder /MQL4/Files/, then you would use the following: #resource"\\Files\\testbild.bmp";
Then add the image to the chart using whatever code you've created then use "::Files\\testbild.bmp" for your path.