[QUOTE][URL=https://www.gisweb.ru/forum/user/17491/]BBV[/URL] написал:
Добрый день!
Пишу на C#
Проблема с функцией mapGetRstFrame.
Написал автоматизированную обработку растровых изображения и заметил что местами появляются точки которых не должно быть. Залил с помощью mapPutRstFrame весь растр. Набросал тестовый код:
int bwidth = (int)Math.Round(bframe.width / 8.0); // ширина фрейма в байтах
int left = 8 * (int)(bframe.left / 8.0); // выравнивание на границу байта
IntPtr bits = Marshal.AllocHGlobal(bcount);
long n = FMapAPI.mapGetRstFrame(hMap, msrc, bits, left, bframe.top, bframe.width, bframe.height, bwidth);
Marshal.Copy(bits, bsrc, 0, bcount);
//Marshal.FreeHGlobal(bits);
// отправляем в pictureBox
gur.DraweFrom1bitArray(picBox, bsrc, bframe.width, bframe.height, Color.Blue, Color.White);
//bits = Marshal.AllocHGlobal(bsrc.Length);
//Marshal.Copy(bsrc, 0, bits, bsrc.Length);
FMapAPI.mapPutRstFrame(hMap, msrc, bits, left, bframe.top, bframe.width, bframe.height, 1, bwidth);
FMapAPI.mapUpdateRstDuplicates(hMap, msrc);
FMapAPI.mapSaveRst(hMap, msrc);
Marshal.FreeHGlobal(bits);
mvMap.Repaint();
Для проверки отправляем считанное изображение в pictureBox (на картинке слева синяя). Растр 1 бит на элемент.
По изображению идут точки. Что не так?[/QUOTE]
Добрый день!
Алгоритм проверки функции mapGetRstFrame:
1. Создано тестовое приложение на С++ для платформы x64 в XE5.
Исходные тексты приложения в архиве Source_Test.zip.
[CODE]//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner), HMap()
{
Bits = 0;
SizeOfBits = 0;
FlagPaint = 0;
FlagGetFrame = 0;
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
DELETE_ARR(Bits);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button_OpenFileClick(TObject *Sender)
{
if (OpenDialog1->Execute())
{
InputName = OpenDialog1->FileName;
Edit1->Text = InputName;
}
HMap = mapOpenDataUn(InputName.c_str());
if (!HMap)
{
mapErrorMessageUn(IDS_OPEN, InputName.c_str());
}
FlagGetFrame = 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button_GetFtameClick(TObject *Sender)
{
if (InputName.IsEmpty())
{
mapErrorMessageUn(IDS_OPEN, L"*.RSW");
return;
}
if (!HMap)
{
mapErrorMessageUn(IDS_OPEN, InputName.c_str());
return;
}
// Размеры отображаемой части тестового растра
int width = 1024;
// Установить ширину кратно байту
width = (width + 7) & ~7;
int height = 1024;
int widthInByte = (width * 1) >> 3;
SizeOfBits = widthInByte*height;
DELETE_ARR(Bits);
NEW_ARR(Bits, char, SizeOfBits);
if (Bits == 0)
{
mapErrorMessageUn(IDS_MEMORY, InputName.c_str());
return;
}
int left = 0;
int top = 0;
// Чтение прямоугольного участка растра
// hMap - идентификатор открытой векторной карты
// number - номер файла в цепочке
// bits - указатель на начало изображения битовой области
// left - смещение слева в элементах (выравнено на границу байта)
// top - смещение сверху в элементах
// width - ширина в элементах (выравнено на границу байта)
// height - высота в элементах
// widthinbyte - ширину прямоугольного участка растра в байтах
// Принцип выравнивания:
// при ElementSize() == 1 (бит) - left,width кратны 8,
// == 4 (бит) - left,width кратны 2
// При ошибке возвращает 0
int ret = mapGetRstFrame(HMap, 1, Bits, left, top, width, height);
if (ret == 0)
{
mapErrorMessageUn(IDS_READ, InputName.c_str());
return;
}
PaintImage(width, height, Bits, SizeOfBits);
}
//---------------------------------------------------------------------------
int __fastcall TForm1::PaintImage(int width, int height, char* bits, int sizeOfBits)
{
if (width == 0 || height == 0 || bits == 0 || sizeOfBits == 0)
return 0;
// Очистить область рисования
TRect rect;
rect.Left = 0;
rect.Top = 0;
rect.Right = Image1->Width;
rect.Bottom = Image1->Height;
Image1->Canvas->FillRect(rect);
PiantFrame(width, height, bits, sizeOfBits);
return 1;
}
//---------------------------------------------------------------------------
int __fastcall TForm1::PiantFrame(int width, int height, char* bits, int sizeOfBits)
{
if (FlagPaint)
return 0;
if (width == 0 || height == 0 || bits == 0 || sizeOfBits == 0)
return 0;
int widthInByte = (width * 1) >> 3;
TColor redColor = TColor(RGB(255, 0, 0));
TColor blueColor = TColor(RGB(0, 0, 255));
TColor currentColor;
for (int j = 0; j < min(Image1->Height, height); j++)
{
char* str = (bits + widthInByte*j);
for (int i = 0; i < min(Image1->Width, width); i++)
{
char* pix = str;
int offset = i;
pix += offset>>3;
int value = (unsigned char)(*pix >> (7-offset%8)) & 0x01L;
if (value == 0)
currentColor = redColor;
else
currentColor = blueColor;
Image1->Canvas->Pixels[i][j] = currentColor;
}
}
return 1;
}
[/CODE]
2. Для выполнения приложения библиотеки GTK x64 изъяты из дистрибутива
"Инструментарий разработчика ГИС-приложений GIS ToolKit (версия 14.5.2.0, для платформ "x32" и "x64")", размещенного на страничке "Скачать" нашего сайта.
[URL=https://www.gisinfo.ru/products/gistool_win.htm]https://www.gisinfo.ru/products/gistool_win.htm[/URL]
Версия библиотек GTK x64 на скриншоте "Свойства: gis64acces.dll".
3. В редакторе Paint создан одноцветный (1 бит на пиксель) файл BMP Line_1024х1024.bmp размером 1024 на 1024 пикселей. По диагонали проведена черная линия.
4. Средствами ГИС Панорама файл Line_1024х1024.bmp конвертирован в растровую карту Line_1024х1024.rsw. Растр размещен в архиве Line_1024х1024.zip.
5. В тестовом приложении открыт файл Line_1024х1024.rsw и по нажатию на кнопку "GetFrame" выполнена функция mapGetRstFrame, далее содержимое буфера отображается на форме Test. Пиксели растра со значение 0 отображаются красным цветом, единички - синим. Отображение содержимого буфера реализовано в функции TForm1::PiantFrame().
При отображении на форме содержимого буфера, полученного вызовом функции mapGetRstFrame, изображение полностью соответствует исходному растру RSW.
Функция mapGetRstFrame работает корректно.