ResourceReadImage - двумерный массив

 

Для ResourceReadImage указано, что массив для получения данных из графического ресурса может быть одномерный или двумерный:

ResourceReadImage

Читает данные графического ресурса, созданного функцией ResourceCreate() или сохраненного в EX5-файле при компиляции.

bool  ResourceReadImage(
   const string      resource_name,       // имя графического ресурса для чтения
   uint&             data[],              // массив для получения данных из ресурса
   uint&             width,               // для получения ширины картинки в ресурсе
   uint&             height,              // для получения высоты картинки в ресурсе
   );

Параметры

resource_name

[in]  Имя графического ресурса, содержащего изображение. Для доступа к собственным ресурсам указывается в коротком виде "::resourcename". Если же необходимо загрузить ресурс из скомпилированного EX5-файла, то необходимо имя в полном виде с указанием пути относительно папки MQL5, имени файла и имени ресурса – "path\\filename.ex5::resourcename".

data[][]

[in]  Одномерный или двумерный массив для получения данных из графического ресурса.

img_width

[out]  Ширина картинки графического ресурса в пикселях.

img_height

[out]  Высота картинки графического ресурса в пикселях.


Интересует реализация двумерного массива. Как нужно прописывать размерность этого массива? На данный момент получаю ошибку 4011: 

Запрашиваемый размер массива превышает 2 гигабайта

 для исходной картинки *.bmp 1366*768 и размером 3Мб.

Файлы:
 

Картинка - это скриншот экрана сохранённый в расширении *.bmp. Путь сохранения: ...\MQL5\Files\Images.

Код скрипта:

//+------------------------------------------------------------------+
//|                                        TestResourceReadImage.mq5 |
//|                              Copyright © 2015, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Test ResourceReadImage"
#include <Canvas\Canvas.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- creating a resource
   ResetLastError();
   if(!ResourceCreate("res","\\Files\\Images\\screen.bmp"))
      Print("Error creating a resource ",GetLastError());
   uint res_data[][10];
   uint res_width=0;
   uint res_height=0;
//---  reads data from the graphical resource
   ResetLastError();
   if(!ResourceReadImage("::res",res_data,res_width,res_height))
     {
      Print("Error reads data from the graphical resource ",GetLastError());
      ResetLastError();
      Print("attempt number two");
      if(!ResourceReadImage("::res",res_data,res_width,res_height))
         Print("Error reads data from the graphical resource ",GetLastError());
     }
//--- 
   Print("Size of resource ",ArraySize(res_data));
   Print("Width ",res_width,", Height ",res_height);
   ResourceFree("res");
  }
//+------------------------------------------------------------------+
 

Разобрался - для функции ResourceReadImage нужно указывать одномерный массив. При этом размер массива, после отработки ResourceReadImage, будет равен ширина_картинки*высота_картинки.

А вот пример работы с ресурсом - из картинки создаётся ресурс, затем ресурс обрабатывается и формируется картинка №2 - изменённая:

//+------------------------------------------------------------------+
//|                                                        Gauss.mq5 |
//|                              Copyright © 2015, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Blur image using a Gaussian filter"
#include <Canvas\Canvas.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- creating a resource
   ResetLastError();
   if(!ResourceCreate("res","\\Files\\Images\\screen.bmp"))
      Print("Error creating a resource ",GetLastError());
   uint res_data[];
   uint res_width=0;
   uint res_height=0;
//---  reads data from the graphical resource
   ResetLastError();
   if(!ResourceReadImage("::res",res_data,res_width,res_height))
     {
      Print("Error reads data from the graphical resource ",GetLastError());
      ResetLastError();
      Print("attempt number two");
      if(!ResourceReadImage("::res",res_data,res_width,res_height))
         Print("Error reads data from the graphical resource ",GetLastError());
     }
//--- decomposition of pictures on the components r, g, b
   Print("Size of resource ",ArraySize(res_data));
   Print("Width ",res_width,", Height ",res_height);

   int size=ArraySize(res_data);
   uint res_data_a[];
   ArrayResize(res_data_a,size);
   uint clr,temp;
   uchar r,g,b;
   for(int i=0;i<size;i++)
     {
      temp=res_data[i];
      clr=COLOR2RGB(temp);
      r=(uchar)(GETRGBR(temp)/1.1);
      g=(uchar)(GETRGBG(temp)/1.1);
      b=(uchar)(GETRGBB(temp)/1.1);
      temp=XRGB(r,g,b);
      res_data_a[i]=temp;
     }
   ResetLastError();
   if(!ResourceCreate("res_a",res_data_a,res_width,res_height,0,0,0,COLOR_FORMAT_ARGB_NORMALIZE))
      Print("Error creating a resource a",GetLastError());
   ResetLastError();
   if(!ResourceSave("::res_a","\\Images\\screen1.bmp"))
      Print("Error save resourse ",GetLastError());

   ResourceFree("res");
   ResourceFree("res_a");
  }
//+------------------------------------------------------------------+

 

*.bmp вложить не получается, поэтому, вот скриншот, что было и что получилось:

Затемнение картинки 

 
Осталось дело за малым - придумать, как обработать изображение фильтром размытие Гаусса. Возможно с применением библиотеки Alglib.
 

Гаусса еще не прикрутил, но уже можно размывать изображение screen.bmp, которое лежит по пути: ...\MQL5\Files\Images\screen.bmp. Правда коэффициенты для маски размытия взяты Гауссовы.

Версия 1.01:

//+------------------------------------------------------------------+
//|                                                        Gauss.mq5 |
//|                              Copyright © 2015, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2015, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.01"
#property description "Blur image using a Gaussian filter"
#include <Canvas\Canvas.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- creating a resource
   ResetLastError();
   if(!ResourceCreate("res","\\Files\\Images\\screen.bmp"))
      Print("Error creating a resource ",GetLastError());
   uint res_data[];                    // array for receiving data from the graphical resource
   uint res_width=0;                   // width of the resource
   uint res_height=0;                  // height of the resource
//+------------------------------------------------------------------+
//| reads data from the graphical resource                           |
//+------------------------------------------------------------------+
   ResetLastError();
   if(!ResourceReadImage("::res",res_data,res_width,res_height))
     {
      Print("Error reads data from the graphical resource ",GetLastError());
      ResetLastError();
      Print("attempt number two");
      if(!ResourceReadImage("::res",res_data,res_width,res_height))
         Print("Error reads data from the graphical resource ",GetLastError());
     }
//+------------------------------------------------------------------+
//| decomposition of pictures on the components r, g, b              |
//+------------------------------------------------------------------+
   int size=ArraySize(res_data);
   uint res_data_a[];                  // temp array for receiving data from the graphical resource
   ArrayResize(res_data_a,size);
   uint clr,clr_temp;                  // color in ARGB format
   uchar r_data[],g_data[],b_data[];   // arrays of colors R, G, B
   ArrayResize(r_data,size);
   ArrayResize(g_data,size);
   ArrayResize(b_data,size);
//---
   for(int i=0;i<size;i++)
     {
      clr_temp=res_data[i];
      clr=COLOR2RGB(clr_temp);
      r_data[i]=GETRGBR(clr_temp);
      g_data[i]=GETRGBG(clr_temp);
      b_data[i]=GETRGBB(clr_temp);
     }
//--- matrix 3 * 3
// 0.25 0.4999999999999998 0.25
   for(int i=0+1;i<size-1;i++)
     {
      r_data[i]=(uchar)(r_data[i-1]*0.25+r_data[i]*0.4999999999999998+r_data[i+1]*0.25);
      g_data[i]=(uchar)(g_data[i-1]*0.25+g_data[i]*0.4999999999999998+g_data[i+1]*0.25);
      b_data[i]=(uchar)(b_data[i-1]*0.25+b_data[i]*0.4999999999999998+b_data[i+1]*0.25);
      clr_temp=XRGB(r_data[i],g_data[i],b_data[i]);
      res_data_a[i]=clr_temp;
     }
   ResetLastError();
   if(!ResourceCreate("res_a",res_data_a,res_width,res_height,0,0,0,COLOR_FORMAT_ARGB_NORMALIZE))
      Print("Error creating a resource a",GetLastError());
   ResetLastError();
   if(!ResourceSave("::res_a","\\Images\\screen1.bmp"))
      Print("Error save resourse ",GetLastError());
//---
   ResourceFree("res");
   ResourceFree("res_a");
  }
//+------------------------------------------------------------------+
 
Karputov Vladimir:

Ужс... Твои платные коды так же написаны?

 
Комбинатор:

Ужс... Твои платные коды так же написаны?

Вечером сударя тянет поговорить?
 
Значит так же
 

ResourceReadImage записывает изображение в одномерный массив в такой последовательности:

ResourceReadImage

 

Зная это, теперь можно организовать двухпроходное размытие: сначала по горизонтали рисунка, а затем по вертикали рисунка.

 
Karputov Vladimir:
Вечером сударя тянет поговорить?
Вам бы все же стоит задуматься и проанализировать свой код. Например, следует ли после получения критической ошибки дальше исполнять скрипт...
 
Yury Kulikov:
Вам бы все же стоит задуматься и проанализировать свой код. Например, следует ли после получения критической ошибки дальше исполнять скрипт...

Я на этом скрипте только обкатываю новое для меня - обработку изображений и это ещё и отладочный код. По возможности нужно фиксировать все ошибки которые могут произойти - хотя бы для того, чтобы знать их в лицо. Поэтому я нигде не прерываю выполнение. 

А вот если есть мысли по применению размытия - пожалуйста делитесь. 

Причина обращения: