如何在保持纵横比且不切断图像数据的情况下跨横向和纵向显示图像

Posted

技术标签:

【中文标题】如何在保持纵横比且不切断图像数据的情况下跨横向和纵向显示图像【英文标题】:How to display a QImage across landscape & portrait orientations with aspect ratio maintained & not cutting off image data 【发布时间】:2017-12-11 11:47:29 【问题描述】:

我有一个QIMage,它可以是纵向或横向模式,具体取决于它的width vs height。或相反亦然。

我正在尝试在不破坏纵横比的情况下适应 横向模式的纵向 QIMage纵向模式的横向 QImage

以下是我尝试这样做的方式:

Window 
  id: app_window
  visible: true

  Rectangle 
    id: my_image_view_container
    width: my_image.sourceSize.width
    height: my_image.sourceSize.height

    // This is a Image item which has to host a portrait/landscape image.jpg in both portrait & landscape modes on an android device
    Image 
       id: my_image
       anchors.fill: parent
       // changes at runtime based on the image my app selects
       source: "random/path/to/an/image.jpg"
       scale: Qt.KeepAspectRatio
    
  

它基本上可以保持纵横比。当我将app_window 从纵向调整为横向时,图像没有倾斜。

问题: 但在横向模式下,如果app_window 的高度小于my_image 的高度,则图像不会完全可见。

问题: 我应该如何设置 my_image_view_containermy_image 的大小,以便能够在横向和纵向两个方向上托管 image.jpg 而不会破坏纵横比,并且不会错过以任何模式查看图像的部分内容?

PS:挑战例如:我拍摄了一个 QML 快照并创建了一个 100 单位宽 x 300 单位高的 QImage。现在更改移动设备的方向或将桌面上的窗口大小调整为横向。现在,我需要将 300 单位高度的 QIMage 调整为 100 单位的高度。如何设置 QIMage 的宽度和高度来很好地完成这个?我看到,当您在横向模式下查看纵向捕捉图像时,Android 上的 Google 照片通过在图像的两侧嵌入黑色来很好地做到这一点,反之亦然。我希望完全实现谷歌照片的这个功能。应该可以通过设置 Image QML 元素的正确宽度和高度来实现吗?

【问题讨论】:

【参考方案1】:

对于您的情况,您可以使用绑定来根据当前像素密度和屏幕状态选择不同的图像。根据官方文档:

绑定使对象能够自动更新其属性,以响应其他对象的属性更改或某些外部事件的发生。

查看现代 Qt 中有关 Scalability 的文档,我认为这非常有用。您可以通过比较宽度和高度轻松检查屏幕的当前状态、横向或纵向情况:

 parameter:  width > height ? contition_1 : condition_2

在您的情况下,我会建议根据状态使用 2 个不同的图像。在官方文档中,您可以找到一个Orientation Observer,旨在为绑定做您想做的事情。顺便说一句,你可以这样做:

Image 
   source: 
      if (width > height)
        "image_1.png"
      else
        "image_2.png"
    

[更新]

或者,如果你想使用相同的图像,你可以处理Screen类的属性方向。如果您适合图像大小,通过属性宽度、高度到 Screen.width 和 Screen.height 属性就足够了。如果您打算使用自定义代码,那么:

Image 
    id: image
    source: "image.jpg"
    width: whatever
    height: whatever 
    fillMode: Image.PreserveAspectFit
    anchors.top: parent.top

    Screen.onOrientationChanged: 
       if (Screen.primaryOrientation === Qt.PortraitOrientation) 
          image.width = 300;
          image.heigh = 100; 
        else 
          image.width = 100;
          image.heigh = 300;
       
    

【讨论】:

请注意,我没有根据方向显示不同的图像。参考您的回答,如果其他情况匹配,我需要调整 image_1.png 的大小。不显示image_2.png,这是完全不同的图像 Qt Scalability 在显示基于Screen.PixelDensityhdpildpi 图像时似乎可以使用。请注意,我的案例是一个非常简单的案例,能够在横向模式下显示 portrait QImage 或在纵向模式下显示 landscape QImage 这不是我要找的。我知道屏幕何时从横向变为纵向,反之亦然。 挑战: 例如,假设您拍摄了一张快照并创建了一个 100 单位宽 x 300 单位高的 QImage。现在将方向更改为横向。我需要将 300 单位高度的 QIMage 放入 100 单位的高度。如何做到这一点? 我已经使用 Screen 类添加了对答案的更新,以处理当前屏幕状态的变化并更改图像的大小,您可以使用 Screen.width && Screen.height 来适合屏幕。

以上是关于如何在保持纵横比且不切断图像数据的情况下跨横向和纵向显示图像的主要内容,如果未能解决你的问题,请参考以下文章

根据窗口大小和纵横比缩放图像

给定图像和纵横比的最大裁剪区域

调整图像大小以保持纵横比并使纵向和横向图像尺寸完全相同?

如何在没有纵横比的情况下在 SVG 中保持图像的纵横比

如何在不影响纵横比的情况下将纵向和横向图像显示为网格上的正方形?

如何在正确保持纵横比的情况下进行缩放