• 0
Tot999

TPaintox+Tbitmap

Вопросы

Добрый день! 

Решил покопаться в своей старой спрайтовой игрушке, чтобы освежить в памяти знания и состряпать что-нибудь новое. Возникли сомнения, нормально ли сделано графическое отображение, можно ли доработать.

Все спрайты в дизайнтайме распиханы по Timagelist-ам.  На старте приложения я загружаю битмапы из имэджлистов в свои обджектлисты, подгоняя под нужный размер. 

MeduzasBitmpAr : array [1..numofMeduzas] of TObjectList<Tbitmap>;

 

Спойлер



//загрузка медуз
  for i := 1 to numofMeduzas do begin
     MeduzasBitmpAr[i]:=  TObjectList<Tbitmap>.create;

      for k := 0 to TImageList(FindComponent('ImageListMedusa'+inttostr(i))).Count-1 do begin
       LoadedBitmap := tbitmap.Create;

       cx:=  settings.standartx* Power(settings.xprop, i);
       cy:=  settings.standarty* Power(settings.yprop, i);

       arectf.Top:= 0 ;
       arectf.left:= 0 ;
       arectf.width:= cx ;
       arectf.height:= cy ;

       LoadedBitmap.Assign(TImageList(FindComponent('ImageListMedusa'+inttostr(i))).Bitmap(arectf.Size,k));

       ResizeBitmap(LoadedBitmap, trunc(cx), trunc(cy));
       MeduzasBitmpAr[i].Add(LoadedBitmap);
      end;
  end;


 

Дальше рисую по таймеру в основном окне игры Tpaintbox.OnPaint:
         

Спойлер

 

 


srcrect.left:= 0  ;
           srcrect.top:= 0  ;
           srcrect.Width:= MeduzasBitmpAr[Creatures[i].level][Creatures[i].AnimationIndex].Width;
           srcrect.height:= MeduzasBitmpAr[Creatures[i].level][Creatures[i].AnimationIndex].height;

           dstrect.left:=Creatures[i].RectF.Location.x-mapdx;
           dstrect.top:= Creatures[i].RectF.Location.y-mapdy;
           dstrect.Width:=Creatures[i].RectF.Width;
           dstrect.height:=Creatures[i].RectF.height;

           bufbitmap.Assign(MeduzasBitmpAr[Creatures[i].level][Creatures[i].AnimationIndex]);

            if ((Creatures[i].angle < 90)and(Creatures[i].angle >= 0)) then begin
               angle:= 180 + Creatures[i].angle;
               end else begin

                  if ((Creatures[i].angle <= 360)and(Creatures[i].angle > 270))  then begin
                    angle:= 180+ Creatures[i].angle;
                  end else begin
                     if (Creatures[i].angle > 90)and(Creatures[i].angle <= 270) then begin
                        bufbitmap.FlipHorizontal;
                       angle:=  Creatures[i].angle;
                     end else begin
                         if (Creatures[i].angle = 90) then begin
                           angle:= 270;
                         end;
                     end;
                  end;
             end;

           PaintBoxMain.BeginUpdate;
           DrawBitmapRotate(PaintBoxMain.Canvas,bufbitmap , srcrect, dstrect, 1 , true, degtorad(angle));
           PaintBoxMain.EndUpdate;


 

В принципе, даже на слабеньких телефончиках, всё вроде бодро. Но может, опытные товарищи чего подскажут, а то я 3ий день в собственном соку варюсь, ничего толкового.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 ответ на этот вопрос

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От PavelS
      Здравствуйте! Начал изучать FireMonkey  и столкнулся с тем, что TBitmap не поддерживает размер изображения больше 8132, кажется. Т.е. большие размеры рисунка он грузит, но за счёт потери качества, размер пиксела растёт, а размер рисунка по оси всё равно не превышает 8132. В то же время в простом дельфи можно грузить и работать с гораздо большими размерами, например, один из файлов имеет размер 61216 х 1486 точек. Подскажите пожалуйста, есть ли возможность работать с большими файлами в FireMоnkey и как это можно организовать? Программа создаётся для работы только в Windows.
    • От x11
      Можно ли получить TBitmap из TBitmapImage? Конвертировать.
    • От Freezer_86
      Пишу кроссплатформенное приложение. Результат поиска отображается в TGrid. Стал вопрос отображения картинки в одной из колонок.
      На Windows все ок, но на планшете происходят просто чудеса: при первом отображение все корректно, но если простоколить вверх-вниз как картинки одни перетираются другими, часть вообще отображается вверх ногами.
      Код для сохранение картинки(jpg) в базу:
      if Assigned(sm) then begin sm.Position := 0; //TBlobField(dmData.cdsPlayerData.FieldByName('Photo')).LoadFromStream(sm); vImage := TImage.Create(nil); try sm.Position := 0; vImage.Bitmap.LoadFromStream(sm); vKoef := vImage.Bitmap.Height / 64; vImage.Bitmap.Resize(Trunc(vImage.Bitmap.Width / vKoef), Trunc(vImage.Bitmap.Height / vKoef)); sm.Free; sm := TMemoryStream.Create(); try vImage.Bitmap.SaveToStream(sm); TBlobField(dmData.cdsPlayerData.FieldByName('SmallPhoto')).LoadFromStream(sm); finally sm.Free; end; finally vImage.Free; end; end{if}; До скрола:

      После скрола:

      Пробовал и LiveBinding, и ручную прорисовку - результат один и тот же. Есть идеи что не так?
      P.S. Знаю что нужно делать через TListView, но заказчик хочет «сеточку как в старой программе», так как на android будет работать только на планшетах – я согласился.
       
    • От Barbanel
      Здравствуйте!
      Стоит задача загружать фотографии и отображать их в списке. Казалось бы, как два пальца, но...
      Код работал долгое время, все грузилось и отображалось. Спустя какое-то время, фото грузиться перестали. Дебаггинг выявил, замкнутый бесконечный цикл в этой процедуре:
      procedure TBitmap.AssignFromSurface(const Source: TBitmapSurface); var BitmapData: TBitmapData; MaxSize: Integer; ResampledSurface: TBitmapSurface; I: Integer; SourceRect: TRectF; begin MaxSize := CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize); <-- MaxSize = 0 if (Source.Width > MaxSize) or (Source.Height > MaxSize) then begin SourceRect := TRectF.Create(0, 0, Source.Width, Source.Height); SourceRect.Fit(TRectF.Create(0, 0, MaxSize, MaxSize)); ResampledSurface := TBitmapSurface.Create; try ResampledSurface.StretchFrom(Source, Trunc(SourceRect.Width), Trunc(SourceRect.Height), PixelFormat); AssignFromSurface(ResampledSurface); <-- infinity loop here finally ResampledSurface.Free; end; end else begin SetSize(Source.Width, Source.Height); if Map(TMapAccess.Write, BitmapData) then try for I := 0 to TBitmapSurface(Source).Height - 1 do Move(TBitmapSurface(Source).Scanline[I]^, BitmapData.GetScanline(I)^, BitmapData.BytesPerLine); finally Unmap(BitmapData); end; end; end; В самом начале процедуры MaxSize получает значение 0 (ноль!), размеры картинки больше нуля и процедура влетает в бесконечный цикл на строке
            AssignFromSurface(ResampledSurface);
       
      Кто-то сталкивался? Есть мысли как лечить?
      Всем спасибо!
    • От hryasch
      Добрый день. Существует одна проблема, с которой уже несколько недель не могу справиться. Есть старый код под WinAPI, его нужно переделать под Android через firemonkey. И главная проблема - есть код, который из собственного формата делает HBITMAP из WinAPI. Фактически это структура, где последнее поле - указатели на биты. Это переделать легко, создав собственную копию такой структуры. Но теперь мне нужно перевести ее в TBitmap, и я не очень понимаю как это сделать.
       
    • От Alex7wrt
      Часто при отрисовке битмапа на холсте используется метод DrawBitmap, где, в частности, в качестве аргумента необходимо указать прямоугольные области источника (SrcRect) и приемника (DestRect). Эти прямоугольники имеют формат записи (Left, Top, Right, Bottom).
      При указании в качестве SrcRect всего битмапа целиком как здесь на формуме так и в книге Осипова я встречал такую запись:
      RectF(0,0,ABitmap.Width,ABitmap.Height) Но моя логика подсказывает, что такой битмап должен иметь размеры на 1 пиксель по горизонтали и вертикали больше, чем на самом деле, ведь первый пиксель имеет координаты (0;0), а последний (ABitmap.Width,ABitmap.Height). Что, наверное, приводит к искажениям при отображении битмапа на холсте.
      Мне думается, что при рисовании целого битмапа следует писать так:
      RectF(0,0,ABitmap.Width-1,ABitmap.Height-1) Прав ли я или не прав? Если нет, то почему?
    • От AlexG
      Привет, друзья!
      Подскажите - как, с максимально возможной скоростью, определить отсутствие изображения как такового в TBitmap?
      Т.е. - есть TBitmap. Он либо заполнен изображением (картинка), либо он - абсолютно черный прямоугольник.
      Каким способом можно узнать - что в нем именно изображение? Т.е. - НЕ абсолютно черный прямоугольник...
      И определить это нужно "мгновенно" (условно выражаясь).
      Заранее всем благодарен за участие!
      P.S. Варианты типа того что ниже - не предлагать)) Хотелось бы что-то "побыстрее"! Еще раз спасибо!
      function IsBitmapEmpty(Bmp: TBitmap): Boolean; var X, Y : Integer; BmpData: TBitmapData; yAddr : Integer; AlphaCount : integer; begin Result := False; try AlphaCount := 0; Bmp.Map(TMapAccess.Read, BmpData); for Y := 0 to Bmp.Height div 2 do begin YAddr := Y * Bmp.Height; for X := 0 to Bmp.Width - 1 do if (PAlphaColorArray(BmpData.Data)^[YAddr + X] <> TAlphaColorRec.Null) and (PAlphaColorArray(BmpData.Data)^[YAddr + X] <> TAlphaColorRec.Black) then begin inc(AlphaCount); Break; end; if AlphaCount > 0 then Break; end; finally Bmp.Unmap(BmpData); Result := AlphaCount = 0; end; end;  
    • От Vizit0r
      Delphi Seattle, Android 5.0.1
      Формирую картинку через ScanLine. На выходе полученный битмап рисуется на полотне TImage, на котором перед этим был нарисован Rect.
      GlobalBitmap - формированный tbitmap.
                 with ObjectPreviewImage.Bitmap.Canvas do             begin               BeginScene;               Clear(TAlphaColorRec.White);               DRect := TRectF.Create(0, 0, GlobalBitmap.Width + 8, GlobalBitmap.Height + 8);               DrawRect(DRect, 0, 0, AllCorners,                        StealthForm.ObjectPreviewImage.AbsoluteOpacity);               DRect := TRectF.Create(0, 0, GlobalBitmap.Width, GlobalBitmap.Height);               DrawBitmap(GlobalBitmap,DRect,                  TRectF.Create(2, 2, GlobalBitmap.Width + 2, GlobalBitmap.Height + 2), 1);               EndScene;             end;  
      Проблема собственно в чем - в андроидной версии слева и внизу рамка "съедается". В Win32 версии все отлично. На прилагаемых скриншотах это четко видно.
      Документацию читал, гугл гуглил.
       
      Что я делаю не так? Или это неизвестные подводные камни андроидного рисования на полотне?
       
      P.S. Картинка одинаковая, цвет к определенной области применяется не верно. Походу тоже андроидные приколы. Но с этим я уже разберусь.
      P.P.S. Уже разобрался с цветом - под андроидом Blue и Red в пикселе надо поменять местами. А насчет канвы - не получается никак.
      P

    • От ra.eremeev
      Друзья, выручайте!
       
      Уже на сутки "завис"...
       
      Приложение под Android должно загружать картинки в TListViewItem (аватарки) с HTTP.
      Ресурс доступен. Картинки на нем тоже.
       
      Использую iDHTTP (iDHTTP тоже "кидал" на форму и создавал динамически - результат один) и TMemoryStream.
      Код ниже.
       
      Само приложение на устройстве выдает ошибку: Access violation at address 559E45CC accessing address 00000000
      Отладчик выдает: class segmentation fault 11
       
      Опытным путем установил, что ошибка, скорее всего, возникает при попытке заполнения TMemoryStream (пробовал TMemoryStream.LoadFromFile - то же самое, хотя приложением TListViewItem.BitMap.LoadFromFile с этим же файлом проходит на ура и все работает).
       
      Во всех случаях используются PNG-картинки небольшого размера и разрешения: 20-25 кБ.
      В коде адрес картинки указан тестовый осознанно (в приложение картинка по используемому адресу доступна).
       
       
      Часть кода:
      var item:TListViewItem;       pic:TMemoryStream;       idhttp1:tidhttp; ... idhttp1.Create(Application); pic:=TMemoryStream.Create; try  IdHTTP.Get('http://site.ru/icons/icon.png, pic);     try      Item.Bitmap.LoadFromStream(pic);      except     end;     finally     pic.Free;     IdHTTP1.Free;    end; Вопроса 2:
      Что я делаю не так? Подскажите, пож-та, хороший пример для выполнения такой задачи (желательно с применением потоков - чтобы приложение не висло на период загрузки данных из HTTP). Спасибо большое!
       
       
    • От Navovvol
      Как вывести текст на изображение так, чтобы его можно было сохранить в .jpg формате.
      P.S. Нет метода TextOut у Image.
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу