Bitmap % screen

 
Hello everyone. 
We would like to create a pannel that contain a picture as header.  The problem with bitmaps is that they are x pixels high and y pixels wide and on a high resolution screen they will appear smaller. I don't know of any way to adjust for this? 
Thank you ! 
 

Hello .

Try this 

#property version   "1.00"
//place your header in the \MQL5\Files directory
#resource "\\Files\\your_header.bmp"
input int min_difference_in_pixels_on_axis_for_redraw=20;//Min Difference In Pixels On Axis For Redraw
input double header_max_x_of_screen_percentage=80.0;//Max % Of X axis used by header
input double header_max_y_of_screen_percentage=50.0;//Max % Of Y axis used by header 
input double header_position_x_as_screen_percentage=10.0;//Header PositionX as %
input double header_position_y_as_screen_percentage=0.0;//Header PositionY as %
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
bool system_busy=true;
uint originalPixels[],originalWidth,originalHeight;//receivers of pixel data , image width and image height
string used_resource_name="HEADER",system_objects_tag="FORUM_";
int screen_x,screen_y;
void dump(bool remove_original){if(remove_original){ArrayFree(originalPixels);originalWidth=0;originalHeight=0;}ResourceFree(used_resource_name);ObjectsDeleteAll(ChartID(),system_objects_tag);}
int OnInit()
  {
//--- create timer
    system_busy=true;
    dump(true);
    bool read=ResourceReadImage("::Files\\your_header.bmp",originalPixels,originalWidth,originalHeight);
    if(read){
    display_header(originalPixels,((int)originalWidth),((int)originalHeight),ChartID(),0,system_objects_tag+"_DISPLAY",header_max_x_of_screen_percentage,header_max_y_of_screen_percentage,header_position_x_as_screen_percentage,header_position_y_as_screen_percentage);
    system_busy=false;
    }else{Print("Cannot read resource");return(INIT_FAILED);}
//---
   return(INIT_SUCCEEDED);
  }
  
void display_header(uint &pixels[],//reference to original pixels 
                    int image_x,int image_y,//original size 
                    ulong chart_id,//id of chart
                    int   subwindow,//subwindow
                    string object_name,//object name for display
                    double screen_x_fill_max_percentage,//max x axis fill allowed
                    double screen_y_fill_max_percentage,//max y axis fill allowed
                    double screen_x_offset_percentage,//position of header in %
                    double screen_y_offset_percentage){
//get size limits from screen
  screen_x=(int)ChartGetInteger(chart_id,CHART_WIDTH_IN_PIXELS,subwindow);
  screen_y=(int)ChartGetInteger(chart_id,CHART_HEIGHT_IN_PIXELS,subwindow);
  
  double max_sx=(((double)screen_x)/100.0)*screen_x_fill_max_percentage;
  double max_sy=(((double)screen_y)/100.0)*screen_y_fill_max_percentage;
  double pos_x=(((double)screen_x)/100.0)*screen_x_offset_percentage;
  double pos_y=(((double)screen_y)/100.0)*screen_y_offset_percentage;
//size of image 
  //a:fit to x axis 
    double image_aspect_ratio=((double)image_x)/((double)image_y);
    double new_x=max_sx;
    double new_y=new_x/image_aspect_ratio;
    //does the new y respect our max fill on the y axis ? yes , good , no recalculate with y axis
      if(new_y>max_sy){
      new_y=max_sy;
      new_x=new_y*image_aspect_ratio;
      } 
   //resize 
     resize_and_resource(pixels,image_x,image_y,((int)new_x),((int)new_y),used_resource_name);
   //object
     ObjectCreate(chart_id,object_name,OBJ_BITMAP_LABEL,0,0,0);
     ObjectSetInteger(chart_id,object_name,OBJPROP_XDISTANCE,((int)pos_x));
     ObjectSetInteger(chart_id,object_name,OBJPROP_YDISTANCE,((int)pos_y));
     ObjectSetInteger(chart_id,object_name,OBJPROP_XSIZE,((int)new_x));
     ObjectSetInteger(chart_id,object_name,OBJPROP_YSIZE,((int)new_y));
     ObjectSetString(chart_id,object_name,OBJPROP_BMPFILE,"::"+used_resource_name);
     ChartRedraw(chart_id);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  system_busy=true;
  dump(true);
  }
void OnTick(){}
void OnTimer(){}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
  if(!system_busy)
   {
   system_busy=true;
   //---
     if(id==CHARTEVENT_CHART_CHANGE)
     {
     int xc=(int)ChartGetInteger(ChartID(),CHART_WIDTH_IN_PIXELS,0);
     int yc=(int)ChartGetInteger(ChartID(),CHART_HEIGHT_IN_PIXELS,0);
     int xdiff=(int)MathAbs(xc-screen_x);
     int ydiff=(int)MathAbs(yc-screen_y);
     if(xdiff>=min_difference_in_pixels_on_axis_for_redraw||ydiff>=min_difference_in_pixels_on_axis_for_redraw){
     ObjectsDeleteAll(ChartID(),system_objects_tag);
     display_header(originalPixels,((int)originalWidth),((int)originalHeight),ChartID(),0,system_objects_tag+"_DISPLAY",header_max_x_of_screen_percentage,header_max_y_of_screen_percentage,header_position_x_as_screen_percentage,header_position_y_as_screen_percentage);
     }
     }
   //---
   system_busy=false;
   } 
  }
//+------------------------------------------------------------------+

bool resize_and_resource(uint &pixels[],int image_width,int image_height,int new_width,int new_height,string resource_name){
if(new_width!=0&&new_height!=0){
if(image_width!=new_width||image_height!=new_height){
double x_step=((double)image_width)/((double)new_width);
double y_step=((double)image_height)/((double)new_height);
double scan_x=0.0,scan_y=0.0;
//new pixels array 
  uint new_pixels[];
  ArrayResize(new_pixels,new_width*new_height);
  //loop to output pixels
    for(int y=0;y<new_height;y++)
    {
    scan_x=0.0;
    for(int x=0;x<new_width;x++)
     {
     double projection_x=scan_x+x_step;
     double projection_y=scan_y+y_step;
       //scan the projected area 
         int from_x=(int)MathFloor(projection_x);
         int from_y=(int)MathFloor(projection_y);
         int to_x=(int)MathFloor(projection_x);
         int to_y=(int)MathFloor(projection_y);
         //color mixeture
           double color_mix=0.0,color_weight_sum=0.0;
           uchar  color_opacity=0;
         for(int py=from_y;py<=to_y;py++)
         {
         for(int px=from_x;px<=to_x;px++)
           {
           //get this original pixels color 
             int co=py*image_width+px;
             if(co>=0&&co<ArraySize(pixels)){
             uint full_color=pixels[co];
             uchar o=(uchar)(full_color>>24);
             uint colors=full_color-(((uint)o)<<24);
             if(o>color_opacity){color_opacity=o;}//retain max opacity
             //find color weight of pixel
               double color_weight=0.0;
               //x
                 //if middle
                   if(px>from_x&&px<to_x){color_weight+=1.0;}
                 //if start
                   else if(px==from_x){color_weight+=(((double)from_x)+1.0)-scan_x;}
                 //if end 
                   else if(py==to_x){color_weight+=projection_x-((double)to_x);}
              //y
                 //if middle
                   if(py>from_y&&py<to_y){color_weight*=1.0;}
                 //if start
                   else if(py==from_y){color_weight*=((((double)from_y)+1.0)-scan_y);}
                 //if end 
                   else if(py==to_y){color_weight*=(projection_y-((double)to_y));}                
             //find color weight of pixel ends here 
             //add to weight sum
               color_weight_sum+=color_weight;
             //add to color mixture 
               color_mix+=((double)colors)*color_weight;  
             }
           }
         }
       //scan the projected area ends here 
       //assemble colors
         if(color_weight_sum>0.0){color_mix/=color_weight_sum;}
         uint colors=(uint)MathFloor(color_mix);
         colors=colors+(((uint)color_opacity)<<24);
         int co=y*new_width+x;
         new_pixels[co]=colors;
     scan_x+=x_step;
     }
    scan_y+=y_step;
    }
  //loop to output pixels ends here
  return(ResourceCreate(resource_name,new_pixels,new_width,new_height,0,0,new_width,COLOR_FORMAT_ARGB_NORMALIZE));
}
else if(image_width==new_width&&image_height==new_height){
return(ResourceCreate(resource_name,pixels,new_width,new_height,0,0,new_width,COLOR_FORMAT_ARGB_NORMALIZE));
}}
return(false);
}

:)

 
Lorentzos Roussos #:

Hello .

Try this 

:)

Thank you very much :)

Reason: