Размери на компонентите в Delphi Android

Създавам приложение за Android в Delphi XE5 с помощта на Firemonkey и за един от моите формуляри имам нужда от TImage, който ще запълни целия формуляр, където мога да рисувам върху неговата Bitmap.

Това, което направих, беше следното:

  1. Добавих компонент TImage към моя формуляр и му зададох Align := alClient. В дизайнера запълва цялата форма.

  2. В моята процедура FormCreate инициализирах Bitmap на TImage, като зададох размера му на размера на TImage

    procedure TDrawForm.FormCreate(Sender: TObject);
    begin
        Image1.Bitmap.SetSize(Trunc(Image1.Width), Trunc(Image1.Height));
        DrawFromList(Image1);
    end;
    
  3. След това рисувам върху Bitmap.Canvas на TImage

    procedure TDrawForm.DrawFromList(image: TImage);
    var draw: TDraw;
    begin
       image.Bitmap.Canvas.BeginScene;
       image.Bitmap.Canvas.Clear(claBlue);
       image.Bitmap.Canvas.Stroke.Color := claBlack;
       image.Bitmap.Canvas.Fill.Color := claYellow;
       for draw in DrawList do
       begin
          image.Bitmap.Canvas.FillPath(draw.fpath, 1);
          image.Bitmap.Canvas.DrawPath(draw.fpath, 1);
       end;
       image.Bitmap.Canvas.EndScene;
    end;
    

Този код рисува добре на моя таблет Nexus 7, но не запълва целия екран:

въведете описание на изображението тук

На втората снимка използвах

Image1.Bitmap.SetSize(Trunc(Image1.Width * 1.34), Trunc(Image1.Height * 1.34));

където 1.34 беше намерен чрез проба и грешка, за да запълни целия екран.

След това се опитах да отпечатам размера на изображението и екрана. За моя Nexus 7 (който е 1280 x 800 пиксела) компонентът TImage, който запълва целия екран, има ширина 601 и височина 880. Така, когато задам размера на Bitmap да бъде размера на моя TImage, растерното изображение също е 601 x 880, което обяснява защо трябваше да мащабирам растерното изображение, за да запълни целия екран. Размерът на екрана се отчита като 600 x 905 (с помощта на Screen.Size).

Моят въпрос е защо размерът на компонента TImage е само 601 x 880 (а екранът само 600 x 905), когато действителната разделителна способност на моето устройство е 800 x 1280? Ако тези размери не са пиксели, тогава какви са? И което е по-важно, как да преобразувам тези числа в реални пиксели на екрана (имайте предвид, че 1.34 работи само за Nexus 7 - на моя HTC Sensation трябваше да е още по-голям)?

Един от моите колеги предположи, че това може да е свързано с DPI на екрана, но не можах да намеря никакъв метод, който да ми даде DPI на текущото устройство.

Също така се опитах да актуализирам размера на растерното изображение в процедурата FormResize, но това не прави разлика.


person Daniel    schedule 18.10.2013    source източник
comment
TImage наистина ли е крайният размер във FormCreate или се коригира отново, за да пасне по-късно? Във FormCreate регистрирайте размера на TImage, след което го направете отново по-късно. Както и да е, ако случаят е такъв, вместо да преоразмерявате растерното изображение, опитайте да използвате TImage.WrapMode за автоматично мащабиране на изображението.   -  person Marcus Adams    schedule 18.10.2013
comment
@MarcusAdams Направих бутон, който отпечатва стойностите и те не се променят. Така че бих казал, че TImage вече има крайния си размер във FormCreate. Имайте предвид, че свойството Screen.Size също дава странни числа (600 x 905 вместо 800 x 1280).   -  person Daniel    schedule 18.10.2013


Отговори (1)


Намерих решение на моя проблем. Очевидно има две свойства на компонента, които ще върнат мащаб. За щастие тази скала, умножена по ширината и височината на компонента, ще върне ширината и височината в пиксели.

Image1.Scene.GetSceneScale
Image1.Canvas.Scale

В моя случай трябваше да инициализирам растерното си изображение по следния начин:

Image1.Bitmap.SetSize(Trunc(Image1.Width * Image1.Canvas.Scale), 
                      Trunc(Image1.Height * Image1.Canvas.Scale));

Това кара Bitmap на моето Image1 да запълва целия екран, тъй като изображението е настроено на Align := alClient.

Все още не знам в какво се измерва оригиналният размер, върнат от Image1.Width и Image1.Height (или Screen.Size за този въпрос), но не винаги е в пиксели. Щеше да ми спести около две седмици главоболие, ако това беше документирано някъде.

person Daniel    schedule 25.10.2013