首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android和Pixels与设备度量

Android和Pixels与设备度量
EN

Stack Overflow用户
提问于 2013-09-17 17:46:32
回答 1查看 249关注 0票数 1

我有个让我发疯的问题。

我有4个功能,可以通过使用密度(1.5)和视图、位图、屏幕等返回的宽度/高度值来调整图像的大小。

这在SG II上工作得很好。但是在HTC野火上,它的密度是0.75 .一些图像在屏幕上得到了大约25%太小的视觉效果.但当我决定将密度覆盖到1.0时,这些图像突然变得合适,而其他图像变得清晰,但尺寸不再正确.把我逼疯了..。

我只能控制我是比较苹果和梨(像素和倾角)的一些地方,但我无法得到符合我所读到的东西的测试,所以为了使某些事情100%确定下来:

..。

我会在下面找到像素吗?还是蘸?:

代码语言:javascript
复制
int bitmapWidth = bitmap.getWidth();

假设欠整齐是一个包含位图的图像视图。像素还是倾角?

代码语言:javascript
复制
int widthParent = view.getWidth();      

下面其实是水底,对吧?

代码语言:javascript
复制
getContext().getResources().getDisplayMetrics().widthPixels;

..。

下面是我的代码不起作用(这段代码给出的位图显示的宽度可能是2/3s,应该是100%),如果检查注释像素值显然是正确的,但最终结果是不正确的:

代码语言:javascript
复制
vto.addOnGlobalLayoutListener(
  new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
      mainLogo.getViewTreeObserver().removeGlobalOnLayoutListener(this);                                                                 
      mainLogo.setScaleType(ImageView.ScaleType.CENTER_INSIDE); // mainLogo = ImageView
      SharedCode.sharedUtilScaleImage_Width(mainLogo, false);              
    }
  }                        
);                                   

// ...

public static void sharedUtilScaleImage_Width(ImageView view, boolean tryBackground)
  {
    Drawable drawing = null;
    boolean useBackground = false;         
    if (drawing == null) {    
      drawing = view.getDrawable();
    }          
    if (drawing == null) {    
      if (tryBackground) {
        drawing = view.getBackground();
        useBackground = true;
      }
    }      
    if (drawing == null) {
      return; 
    }        
    if (!(drawing instanceof BitmapDrawable)) {
      return; 
    }                      
    Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
    if (bitmap == null) {
      return;
    }
    //--                               
    int bitmapWidth = bitmap.getWidth(); // returns 770 (which is correct checking on disk)
    int bitmapHeight = bitmap.getHeight();                
    // float density = 1;
    // density = MicApp.getContext().getResources().getDisplayMetrics().density; // 1.5          
    float widthScreen = MicApp.getContext().getResources().getDisplayMetrics().widthPixels; // returns 480              
    int widthParent = view.getWidth(); // returns 480, should be same as screen      
    //--
    float xScale = ( (float) widthParent / (float) bitmapWidth); 
    Matrix matrix = new Matrix();
    matrix.postScale(xScale, xScale);
    //--
    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth, bitmapHeight, matrix, true);
    int bitmapWidth2 = scaledBitmap.getWidth(); // 480
    int bitmapHeight2 = scaledBitmap.getHeight();      
    //--          
    BitmapDrawable result = new BitmapDrawable(scaledBitmap);          
    //--          
    if (useBackground) {
      LayoutParams layoutparams = new LayoutParams(bitmapWidth, bitmapHeight);
      view.setLayoutParams(layoutparams);
      view.setBackgroundDrawable(result);
    }
    else {
      view.setImageDrawable(result);
    }            
  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-18 14:27:13

在解码图像和显示图像之间有几个步骤。这些步骤通常用于以正确的比例显示资源中的图像。如果您只将一个图像放在/res/drawable-mdpi/中,而不是在其他文件夹中,它仍然可以在其他密度的设备上以正确的大小显示。

如果要在mdpi(320‘ll)设备上加载用于x-hdpi(160’ll)的图像,并希望它以相同的大小显示,则需要将其像素大小增加一倍。例如,需要在200x200像素处显示100x100像素图像。

与缩放有关的地方是

  • 解码图像(例如,参见BitmapFactory.Options#inDensity)。BitmapFactory已经可以将100x100PNG图像解码为200x200映像。
  • Bitmap本身的密度。这是每个位图的属性,用于存储图像的密度。如果BitmapFactory将100 x 100 mdpi图像解码为200 x 200,那么密度实际上会说"I'm x-hdpi“。您还可以在解码时禁用缩放功能,并使用mdpi密度获得100x100图像。显示该图像需要将图像绘制为2x。
  • BitmapDrawable的目标密度,通常是设备的密度。如果BitmapDrawable必须绘制一个密度不匹配的Bitmap,它将绘制一个缩放版本。

来自BitmapDrawable的代码,mTargetDensity应该是设备密度。

代码语言:javascript
复制
private void computeBitmapSize() {
    mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);
    mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);
}

来自BitmapmDensity的相关片段是位图的密度

代码语言:javascript
复制
public int getScaledWidth(int targetDensity) {
    return scaleFromDensity(getWidth(), mDensity, targetDensity);
}

static public int scaleFromDensity(int size, int sdensity, int tdensity) {
    if (sdensity == DENSITY_NONE || sdensity == tdensity) {
        return size;
    }
    
    // Scale by tdensity / sdensity, rounding up.
    return ((size * tdensity) + (sdensity >> 1)) / sdensity;
}
  • 例如,ImageView的缩放选项。如果您想在屏幕上显示一个表示(由于缩放或实际上是)200x200PX的图像的ImageDrawable,则需要在屏幕上显示实际为400x300PX的ImageView中,您需要再次缩放图像。

使用ImageView.ScaleType.CENTER_INSIDE将在200x200PX绘制图像,因为CENTER_INSIDE只在图像大于视图的情况下才在缩放图像。FIT_CENTER将将其扩展到300x300。只是CENTER根本不缩放。它只是中心。

由于存储在CENTER_INSIDE / Bitmap中的所有缩放因子,BitmapDrawable +来自上面的100x100MDPI映像仍然会将其绘制为200x200px。

BitmapFactory > Bitmap > BitmapDrawable > ImageView链中还有其他几个地方,比如BitmapDrawable(Bitmap bitmap)构造函数

这个构造函数在API 4中是不推荐的。使用BitmapDrawable(参考资料,位图)来确保绘图正确地设置了它的目标密度。

这可能会以不想要的方式影响图像缩放。

防止所有缩放的->

  • 无标度解码
  • 确保位图的密度是当前设备密度,或者是简单的Bitmap#setDensity(Bitmap.DENSITY_NONE)
  • 不要在通过ImageView.ScaleType.CENTER绘图时应用缩放。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18856511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档