На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

XIMAGEDESC - получение изображения

Поиск  Пользователи  Правила  Войти
Форум » Настольные приложения » GIS ToolKit, GIS ToolKit Active, ГИС Конструктор для Windows
Страницы: 1 2 3 4 След.
RSS
XIMAGEDESC - получение изображения
 
Добрый. Можно уточнить, по какому алгоритму кодируются данные о изображении в структуре XIMAGEDESC?
В настоящий момент, я имею пример на QT, где выполнено следующее:
Код
   QImage image((uchar *)xImageDesc.Point, exampleWidth, exampleHeight, QImage::Format_RGB32);

Что не расскрывает, каким образом я могу получить изображение на c# Я пытаюсь сделать изображение по принципу BITMAP
Код
public static SystemDrawing::System.Drawing.Bitmap Convert2Bitmap(this XIMAGEDESC imageInfo)
{
    var bytes = imageInfo.GetBytes();
    var bitmap = new SystemDrawing::System.Drawing.Bitmap(imageInfo.Width, imageInfo.Height,PixelFormat.Format32bppRgb);
    
    // Текущая палитра 
    var paletteBitmap = new SystemDrawing::System.Drawing.Bitmap(imageInfo.Width, imageInfo.Height,PixelFormat.Format8bppIndexed);
    for (int i = 0; i < 256; i++)
        paletteBitmap.Palette.Entries[i] = SystemDrawingColor.FromArgb(255, i, i, i);
            
    // Заполняем изображение
    for (int y = 0; y < imageInfo.Height; y++)
    {
        for (int x = 0; x < imageInfo.Width; x++)
        {
            var indexPalette = bytes[x + (y * imageInfo.Width)];
            var color = paletteBitmap.Palette.Entries[indexPalette];
            bitmap.SetPixel(x,y, color);
        }
    }
    
    return bitmap;
}

В результате, я получаю изображение, вида (явно не корректно).
Изменено: George - 28.06.2022 11:06:18
 
Здравствуйте!
Цитата
Alexander Volovikov написал:
В  настоящий момент, я имею пример на QT, где выполнено следующее:
Код
  QImage image((uchar *)xImageDesc.Point, exampleWidth, exampleHeight,  QImage::Format_RGB32);
Исходя из сформированного QImage, XIMAGEDESC.Point заполнен как массив шириной exampleWidth и высотой exampleHeight формата RGB-32 (0xffRRGGBB).
 
Добрый. Константин Ганюшин Выше, я привел пример формирования изображения именно по указанным Вами характеристиками. Посмотрите картинку пжл. Так не работает.
Я задам Вам еще раз вопрос. Как система ГисПонорама формирует массив в структуре XIMAGEDESC?
 
Здравствуйте!

Исходя из анализа приведенного кода из переданной памяти последовательно считывается по одному байту и интерпретируется как индекс палитры:
Цитата
var indexPalette = bytes[x + (y * imageInfo.Width)];
В то время, как в памяти последовательно для каждого цвета располагается четыре байта в формате 0xffRRGGBB.
Пожалуйста, проанализируйте данный участок кода на корректность.
 
Вот, вариант с 4-мя байтами
Код
public static  SystemDrawing::System.Drawing.Bitmap ToBitmap1(this XIMAGEDESC imageInfo)
{
    var bytes = imageInfo.GetBytes();
    var bitmap = new SystemDrawing::System.Drawing.Bitmap(imageInfo.Width, imageInfo.Height,PixelFormat.Format32bppArgb);

    for( int x=0; x< imageInfo.Width * imageInfo.Height * imageInfo.CellSize ; x += imageInfo.CellSize )
    {
        var color = SystemDrawingColor.FromArgb(bytes[x], bytes[x + 1], bytes[x + 2]);
        bitmap.SetPixel((x / imageInfo.CellSize) % imageInfo.Width, x / imageInfo.CellSize / imageInfo.Width, color);
    }

    return bitmap;
}

Результат, практически такой же (см. картинку).

Изменено: George - 29.06.2022 14:03:33
 
А может быть дело в разрешении?  Например - один пиксель одного цвета в ГисПонорама - это не точка, а скажем 6x6 точек.
Код
public static  SystemDrawing::System.Drawing.Bitmap ToBitmap1(this XIMAGEDESC imageInfo)
{
    var bytes = imageInfo.GetBytes();
    var bitmap = new SystemDrawing::System.Drawing.Bitmap(imageInfo.Width, imageInfo.Height, 
        PixelFormat.Format32bppArgb);
    bitmap.SetResolution(10.0F, 10.0F);
    
    for( int x = 0; x< imageInfo.Width * imageInfo.Height * imageInfo.CellSize ; x += imageInfo.CellSize )
    {
        var blue = bytes[x];
        var green = bytes[x + 1];
        var red =  bytes[x + 2];
        var alfa =  bytes[x + 3];

        var color = SystemDrawingColor.FromArgb(red, green, blue);
        //var color = SystemDrawingColor.FromArgb(alfa, red, green, blue);
        bitmap.SetPixel((x / imageInfo.CellSize) % imageInfo.Width, x / imageInfo.CellSize / imageInfo.Width, color);
    }
    
    return bitmap;
}
 
Пример
Изменено: George - 29.06.2022 15:18:21
 
Цитата
Константин Ганюшин написал:
Исходя из сформированного QImage, XIMAGEDESC.Point заполнен как массив шириной exampleWidth и высотой exampleHeight формата RGB-32 (0xffRRGGBB).
Данное описание корректно. На текущий момент мы можем привести пример формирования BITMAP на C++ с сохранением в файл:
Код
Gdiplus::Bitmap* newimage = 0;
try
{
  newimage = new Gdiplus::Bitmap(ximagedesc->Width, ximagedesc->Height,PixelFormat32bppARGB);
}
catch(...)
{
  return 0;
}

Gdiplus::Rect gdrect(0, 0, ximagedesc->Width, ximagedesc->Height);
Gdiplus::BitmapData data;

newimage->LockBits(&gdrect, Gdiplus::ImageLockModeWrite, PixelFormat32bppARGB, &data);
int widthbits = ximagedesc->Width * 4;

BYTE* pSrcPointer = (BYTE*)ximagedesc->Point;
BYTE* pDstPointer = (BYTE*)data.Scan0;

for (int i=0; i < ximagedesc->Height; i++)
{
  memcpy(pDstPointer, pSrcPointer, widthbits);
  if (i == ximagedesc->Height - 1)
    break;

  pSrcPointer = pSrcPointer + widthbits;
  pDstPointer += data.Stride;
}

newimage->UnlockBits(&data);

newimage->Save(outpath, &ImagePngCLSID, NULL);

Дополнительно, уточните, пожалуйста, каким способом Вы выводите и контролируете полученный Bitmap.
 
Добрый. Я написал аналогичную функцию
Код
public static SystemDrawing::System.Drawing.Bitmap ToBitmap(this XIMAGEDESC imageInfo, byte[] bytes)
{
    var bitmap = new SystemDrawing::System.Drawing.Bitmap(imageInfo.Width, imageInfo.Height, 
        PixelFormat.Format32bppArgb);
    
    var widthbits = imageInfo.Width * 4;
    var data = bitmap.LockBits(new Rectangle(0, 0, imageInfo.Width, imageInfo.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    for (int i=0; i < imageInfo.Height; i++)
    {
        var startIndex = widthbits * i;
        var destPointer = (IntPtr)(data.Scan0.ToInt64() + (long)(i * data.Stride));
        Marshal.Copy(bytes, startIndex, destPointer,   widthbits);
    }
    
    bitmap.UnlockBits(data);
    return bitmap;
}

Далее, нарисовал тестовую картинку и ее сконвертировал в массив байт.
Код
public static byte[] ToBytes(this XIMAGEDESC imageInfo, string fileName)
{
    var bytes = new byte[imageInfo.GetSize()];
    
    var bitmap = new SystemDrawing::System.Drawing.Bitmap(fileName);
    BitmapData data=bitmap.LockBits(new Rectangle(0, 0, imageInfo.Width, imageInfo.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    Marshal.Copy(data.Scan0, bytes, 0, imageInfo.GetSize());
    
    bitmap.UnlockBits(data);
    return bytes;
}
Далее, выполнил проверки. Считал изображение и записал его повторно.
Код
var bytes = _imageInfo.ToBytes("/home/valex/Projects/War/Comandor.Net/Docs/Templates/2.bmp");
var bitmap = _imageInfo.ToBitmap(bytes);
bitmap.Save("/home/valex/Projects/War/Comandor.Net/Docs/Templates/1.bmp");
Получил полную копию. Все работает корректно.
Затем, выполняю фцнкцию
Код
mapViewImageToXImage 
Откуда получаю массив из структуры XIMAGEDESC и уже этот массив я записываю в файл и получаю НЕ корректно изображение.
Я делаю вывод, что либо функция mapViewImageToXImage работает не корректно, либо получение массива из структуры XIMAGEDESC нужно делать по другому.
Код
public static byte[] GetBytes(this XIMAGEDESC imageInfo)
{
    var bytes = new byte[imageInfo.GetSize()];
    Marshal.Copy(imageInfo.Point, bytes, 0, imageInfo.GetSize());
    return bytes;
}
 
Изображение под Linux я формирую с использованием библиотеки libgdiplus.so и Nuget пакета CoreCompat.System.Drawing
https://www.nuget.org/packages/CoreCompat.System.Drawing/
Страницы: 1 2 3 4 След.
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности