Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Data To Bitmap


Автор: RamIreZz 30.6.2010, 09:46
Доброго времени суток.

У меня вопрос такого плана:

Имеется Bitmap в виде

Код

{
D6000000424DD60000000000000076000000280000000C0000000C0000000100
0400000000006000000000000000000000001000000000000000000000000000
8000008000000080800080000000800080008080000080808000C0C0C0000000
FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00888888888888
0000888888888888000088888888888800008800888800880000888008800888
0000888800008888000088888008888800008888000088880000888008800888
0000880088880088000088888888888800008888888888880000
}


Нужно его преобразовать в нормальный Битмап. Вопрос как?

Автор: UniBomb 30.6.2010, 10:18
RamIreZz, для этого надо хотя бы знать высоту/ширину битмапа. Я не дока в делфи, но по аналогии с билдером можно воспользоваться свойством ScanLine, который представляет из себя указатель на строку цветов пикселей. Для работы со ScanLine надо сначала установить PixelFormat в соответсвии с размерностью цветовой палитры. Т.е. если в этом массиве каждый цвет выражается четрымя байтами, то необходимо установить PixelFormat в значение pf32bit. 

Автор: RamIreZz 30.6.2010, 10:50
UniBomb, Размер точно известен. 12*12 bmp 8bit

Автор: UniBomb 30.6.2010, 11:35
Цитата(RamIreZz @  30.6.2010,  11:50 Найти цитируемый пост)
16*16 bmp 8bit

Тогда в твоём скопище чисел не хватает чутка. В общем как я и говорил - я не дока в делфи (а в тему забрёл случайно), посему решение показываю на С++. Уж простите меня.

Код

    TRect rect;
    rect.Left = 0;
    rect.Top = 0;
    rect.Right = 16;
    rect.Bottom = 16;
    Graphics::TBitmap *SomeBitmap = new Graphics::TBitmap;
    SomeBitmap->Height = 16;
    SomeBitmap->Width = 16;
    SomeBitmap->PixelFormat = pf8bit;
    BYTE SomePic[16][16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0x00, 0x00, 0x00, 0x42, 0x4D, 0xD6, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
                            0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00,
                            0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00,
                            0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00,
                            0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
                            0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00,
                            0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x88, 0x00, 0x88, 0x88, 0x00, 0x88, 0x00, 0x00,
                            0x88, 0x80, 0x08, 0x80, 0x08, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
                            0x88, 0x88, 0x80, 0x08, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
                            0x88, 0x80, 0x08, 0x80, 0x08, 0x88, 0x00, 0x00, 0x88, 0x00, 0x88, 0x88, 0x00, 0x88, 0x00, 0x00,
                            0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00};
    for(int i = 0; i < 16; i++)
    {
     memcpy((BYTE*)SomeBitmap->ScanLine[i], SomePic[i], 16);
    }
    SomeImage->Canvas->CopyRect(rect, SomeBitmap->Canvas, rect);
    delete SomeBitmap;

Автор: RomanEEP 30.6.2010, 20:02
а вообще преобразуется просто - перебей данные из HEX в обычный массив данных (2 сивмола преобразуются в один байт)
запиши массив в TMEmoryStream, установи позициб в начало и смело грузи TBitmap из этого массива

ЗЫ: По куску C0000000C0000000 мне кажется у тебя картинка 12 на 12

Автор: Alexeis 30.6.2010, 22:06
RomanEEP, одно только дополнение, кусок 4 байта D6000000 лишний и не является частью битмапа. Битмап, как известно, начинается с сигнатуры 42 4D что в ASCII значит BM.

Автор: AntonN 30.6.2010, 23:50
и возможно еще последние...
напомнило это http://forum.sources.ru/index.php?showtopic=295627&st=0

Автор: UniBomb 1.7.2010, 00:56
RomanEEP, Alexeis, а расскажите пожалуйста мне, дебилу, как делается "установи позицию в начало и смело грузи TBitmap из этого массива", ибо мне это тоже будет полезно  smile 

Автор: Alexeis 1.7.2010, 02:23
UniBomb, TBitmap умеет загружать картинку из потока (наследник TStream) при помощи метода LoadFromStream(). Установка в нулевую позицию нужна не всегда. Дело в том, что некоторые классы (использующие LoadFromStream) умеют не просто загружать данные из потока, но делают это начиная с текущей позиции. Если указатель позиции в конце потока, то соответственно ничего прочитать не получиться, поэтому рекомендуется сбрасывать позицию в 0. Насколько я помню, TBitmap хотя довольно топорный класс но тут как раз можно сделать сдвиг на 4 байта от начала и читать битмап дальше (  ReadStream(Stream, Stream.Size - Stream.Position);). Однако если в конце будет мусор, то чтение такого битмапа может привести к непредсказуемым последствиям.

Автор: UniBomb 1.7.2010, 08:11
Alexeis, спасибо, доходчиво  smile 

Автор: UniBomb 1.7.2010, 08:42
А рисунок то действительно имеет размеры 12*12

user posted image

А мой код, который выше, такую ерунду рисует  smile 

Автор: Alexeis 1.7.2010, 09:25
На всякий случай приведу свой вариант кода
Код

const bmpdata : UnicodeString =
                'D6000000424DD60000000000000076000000280000000C0000000C0000000100' +
                '0400000000006000000000000000000000001000000000000000000000000000' +
                '8000008000000080800080000000800080008080000080808000C0C0C0000000' +
                'FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00888888888888' +
                '0000888888888888000088888888888800008800888800880000888008800888' +
                '0000888800008888000088888008888800008888000088880000888008800888' +
                '0000880088880088000088888888888800008888888888880000';

procedure TForm1.Button1Click(Sender: TObject);
var
  m : TMemoryStream;
  b : TBitmap;
begin
  m := TMemoryStream.Create;
  try
    m.Size := Length(bmpdata) div 2;//2 символа на байт
    HexToBin(PWideChar(bmpdata), m.Memory, m.Size);
    b := TBitmap.Create;
    try
      m.Position := 4; //битмап по смещению 4 байта
      b.LoadFromStream(m);
      Canvas.Draw(30,30, b)
    finally
      b.Free
    end
  finally
    m.Free
  end;
end;

Автор: RamIreZz 5.7.2010, 09:19
Alexeis, Спасибо большое, за помощь! А то я с графикой пока ещё не очень дружу. ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)