Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
图像在android上无法正确显示_Android_Delphi_Bitmap_Firemonkey_Delphi Xe8 - Fatal编程技术网

图像在android上无法正确显示

图像在android上无法正确显示,android,delphi,bitmap,firemonkey,delphi-xe8,Android,Delphi,Bitmap,Firemonkey,Delphi Xe8,我对Android上的FMX没有正确显示图像有问题 我的应用程序是我第一次使用Android,它有一个背景和一个启动图像,在应用程序启动时显示。飞溅物显示在所有东西的顶部,然后计时器使其消失,并显示背景 Memu emulator的屏幕截图: 我手机上的屏幕截图: 来源于复制的问题: 我从Delphi6开始编写Pascal,在此之前我从未问过任何与编码相关的问题,但这对我来说是非常新的 到目前为止,我已经试了三天让它工作,但没有运气 目前我正在使用RCDATA资源并从那里加载图像。我甚至尝

我对Android上的FMX没有正确显示图像有问题

我的应用程序是我第一次使用Android,它有一个背景和一个启动图像,在应用程序启动时显示。飞溅物显示在所有东西的顶部,然后计时器使其消失,并显示背景

Memu emulator的屏幕截图:

我手机上的屏幕截图:

来源于复制的问题:

我从Delphi6开始编写Pascal,在此之前我从未问过任何与编码相关的问题,但这对我来说是非常新的

到目前为止,我已经试了三天让它工作,但没有运气

目前我正在使用
RCDATA
资源并从那里加载图像。我甚至尝试将图像放在不同的形式上,就像其他
TImage
组件一样,然后从那里加载。我还注意到,如果图像被设置为
Align=Client
,并且
WrapMode=Center
,那么它们都会被错误地放置在
MainForm
上,但在其他表单上工作得很好。所以现在,我尝试裁剪图像,它们是正方形的,这样它们的纵横比就和它运行的设备一样

我可以继续说下去,因为到目前为止我试过的是一场长谈

procedure TForm1.FormShow(Sender: TObject);
var
  Bmp, BmpSplash: TBitmap;
  iRect: TRect;
begin
  Load_image_from_resource(Form1.Image_bg, '0_bg');
  Load_image_from_resource(Form1.Image_splash, '0_splash');

  Bmp := TBitmap.Create;
  try
    Bmp.Width := round(Form1.Image_bg.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
    Bmp.Height := round(Form1.Image_bg.Bitmap.Height);
    iRect.Width := round(Form1.Image_bg.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
    iRect.Height := Bmp.Height;
    iRect.Left := round((iRect.Height - iRect.Width) / 2);
    iRect.Top := 0;
    Bmp.CopyFromBitmap(Form1.Image_bg.Bitmap, iRect, 0, 0);
    //Form1.Image_bg.Bitmap := nil;
    Form1.Image_bg.Bitmap.Assign(Bmp);
    Form1.Image_bg.Align := TAlignLayout.Client;
    Form1.Image_bg.WrapMode := TImageWrapMode.Stretch;
  finally
    Bmp.DisposeOf;
    Bmp := nil;
  end;

  BmpSplash := TBitmap.Create;
  try
    BmpSplash.Width := round(Form1.Image_splash.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
    BmpSplash.Height := round(Form1.Image_splash.Bitmap.Height);
    iRect.Width := round(Form1.Image_splash.Bitmap.Width * (Form1.ClientWidth / Form1.ClientHeight));
    iRect.Height := Bmp.Height;
    iRect.Left := round((iRect.Height - iRect.Width) / 2);
    iRect.Top := 0;
    BmpSplash.CopyFromBitmap(Form1.Image_splash.Bitmap, iRect, 0, 0);
    //Form1.Image_splash.Bitmap := nil;
    Form1.Image_splash.Bitmap.Assign(BmpSplash);
    Form1.Image_splash.Align := TAlignLayout.Client;
    Form1.Image_splash.WrapMode := TImageWrapMode.Stretch;
  finally
    BmpSplash.DisposeOf;
    BmpSplash := nil;
  end;

  Form1.Image_bg.SendToBack;
  Form1.Image_bg.Visible := False;
  Form1.Image_splash.BringToFront;
  Form1.Image_splash.Visible := True;
  Form1.Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Form1.Timer1.Enabled := False;
  Form1.Image_bg.Visible := True;
  Form1.Image_splash.Visible := False;    
end;

您非常接近,我认为Delphi代码中的以下特性可能让您最头疼:

在代码中有如下内容:

iRect.Width := ...
iRect.Height := ...
iRect.Left := ...
iRect.Top := ...
TRect
(或
TRectF
)由其四个属性决定:
左、上、右、下。
当您使用
宽度
(和
高度
)更改尺寸时,可将此设置程序称为:

// This is the code in XE7, I do not know if it has been changed later
procedure TRect.SetWidth(const Value: Integer);
begin
  Self.Right := Self.Left + Value;
end;
SetHeight
非常相似

当您更改
左侧
顶部
时,只需更改相应的字段,但不会更改
右侧
底部
。结果是
宽度
高度
也会改变

设想一个本地未初始化变量
direct
,它可能具有
Left
Right
的任何值。上面的代码可能会以非常奇怪的
TRect
矩形结束。解决方法是首先设置
属性,然后设置
宽度
高度

要显示图像,您要求它遵循纵横比,这意味着垂直显示图像时需要从图像的侧面(水平显示时从顶部和底部)剪切切片。我使用
direct
进行了此操作,以便将其初始化为屏幕大小,然后用屏幕大小和图像大小之间的差值的一半进行偏移

下面是根据屏幕大小显示图像的代码。这里只有垂直显示,但水平显示将遵循相同的方案。为了简洁起见,我也没有包括splash图像,请使用相同的代码和您自己的更改逻辑。代码中的注释应该可以解释我的想法。正如您看到的,它与您的非常相似,您对
direct.Width
direct.Left
的计算不正确,可能是因为
TRect
的特性

// I feel more comfortable with a bmp as temporary storage than the TImage, therefore this minor mod
procedure Load_Bitmap_From_Resource(var bmp: TBitmap; res_name: String);
var InStream: TResourceStream;
begin
  InStream := TResourceStream.Create(HInstance, res_name, RT_RCDATA);
  try
    Bmp.LoadFromStream(InStream);
  finally
    InStream.Free;
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
var
  ScrHeight, ScrWidth: integer;
  bmp, bmp2, BmpSplash: TBitmap;
  iRect: TRect;
begin
  // Form1 acted for me also as a simulation form during dev, therefore
  // these settings are not meant to be included in actual application
  // ***********
  self.Left := 0; self.ClientWidth  := 270;
  self.Top  := 0; self.ClientHeight := 540;
  // ***********

  // Use FireMonkey Platform Services, IFMXScreeService to get real size of screen
  ScrHeight := 2160; // just arbitrary examples, ..
  ScrWidth  := 1080; // ..for testing use size of your own phone

  // I feel more comfortable with a bmp as temporary storage than the TImage
  bmp := TBitmap.Create;
  try
    Load_Bitmap_From_Resource(bmp, '0_bg');

    iRect := Rect(Point(0, 0), Point(ScrWidth, ScrHeight));
    iRect.Offset((bmp.Width-ScrWidth) div 2, (bmp.Height-ScrHeight) div 2);

    bmp2 := TBitmap.Create;
    try
      bmp2.SetSize(iRect.Width, iRect.Height);
      bmp2.CopyFromBitmap(bmp, iRect, 0, 0);
      Form1.Image_bg.Bitmap.Assign(bmp2);
      Form1.Image_bg.Align := TAlignLayout.Client;
    finally
      bmp2.DisposeOf;
    end;
  finally
    bmp.DisposeOf;
  end;

  Form1.Image_bg.Visible := True;
end;

谢谢你的语法编辑,Remy:-)我发现你的代码有几个问题,但你还没有表达你希望在各种情况下,如水平/垂直不同的显示分辨率等,飞溅图像和背面图像显示的准确程度。请编辑并添加信息。如果我不够清楚,我很抱歉,我尽量不深入细节,因为否则你会读一整本书:-)我希望启动应用程序时显示飞溅图像,几秒钟后它应该消失,背景显示,直到用户关闭应用程序。我提供的源代码只是我尝试过的东西之一,它检测屏幕大小,如果是纵向的,那么它将使用我在这里提供的代码。我没有做过横向,因为我不想在没有另一个先工作的情况下做得更进一步。如前所述,如果我的TImage为align:=client和wrapmode:=center,那么它会将图像放错位置,但不会放在其他表单上。我开始认为这可能是某种内存问题,或者更多的是我不知道的android的局限性,因为当我编译成这样时,它在win32+64上运行良好。我真的希望有人能帮我,因为我开始失去理智了:-)好的,我在考虑分辨率,因为源图像是2160 x 2160。简单的解决方案是根据需要拉伸以适应显示,但会改变文本的外观。可以吗?如果长宽比根据物理显示而变化,这与此无关吗?还有其他要求吗?您还没有说过吗?非常感谢!我只是在我制作的示例/复制代码上尝试了它,它确实起了作用。所以,现在我正在尝试将其实现到我的应用程序中,如果它有效,我将与您联系;-)虚惊一场。。它在Memu emulator上运行,然后我尝试在我的应用程序上实现它,但随后我也在Memu中编译并尝试了它,然后它冻结了一些过程。然后我试了试我的手机,然后它甚至都没有安装。“应用程序未安装。”,它说。然后我试着用你的代码在我的手机上安装我制作的测试应用程序,但也无法安装,因为它给了我同样的信息。为了正确编译Android应用程序,我需要做些什么吗?我开始认为编译器或其他东西可能是问题所在,因为我不明白它应该那么脆弱。德尔福从来没有像我这样不稳定过-/请注意,问答网站也是如此,可以回答特定的问题。它不是一个正在进行的调试服务。您的具体问题是如何修复代码以正确显示背景图像和飞溅图像,而不是问题中显示的错误裁剪图像。我指出了错误