【问题标题】:How to scale bitmap to screen size?如何将位图缩放到屏幕大小?
【发布时间】:2011-09-18 14:47:44
【问题描述】:

我想知道如何将位图缩放到屏幕高度和宽度?

谁能告诉我怎么做。

谢谢 蒙娜丽

【问题讨论】:

  • 你有什么?带有 ImageView 或 Bitmap/Drawable 和 Canvas 的布局?
  • 如果布局是画布,Cordova 会自动缩放画布以适应不同的屏幕尺寸,还是必须自己手动完成?

标签: android


【解决方案1】:

【讨论】:

    【解决方案2】:

    试试这个来解码位图:

    其中 imagefilepath 是图片的路径名,它会在 String 中使用

    转换为 File
    File photos= new File(imageFilePath);
    

    photo图片的文件名,现在您可以根据自己的要求设置高度和宽度。

    public void main(){
        Bitmap bitmap = decodeFile(photo);
        bitmap = Bitmap.createScaledBitmap(bitmap,150, 150, true);
        imageView.setImageBitmap(bitmap);
    } 
    
    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);              
            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale++;
            }
    
            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
            return null;
    }
    

    【讨论】:

    • 这比朴素的实现要好,而且使用的内存更少。
    • 代码有一个小错误。应该是 scale*=2; 而不是 scale++;
    • 我想我有同样的问题,我想我必须使用 LayoutParams?请帮我解决这个问题:stackoverflow.com/questions/21420278/…
    • 与其做所有这些工作来计算 inSampleSize 的比例,你不能只做o2.inSampleSize = (int) (Math.min(width_tmp, height_tmp) / REQUIRED_SIZE); 吗?根据 BitmapFactory.Options.inSampleSize 上的文档,the decoder uses a final value based on powers of 2, any other value will be rounded down to the nearest power of 2。所以我认为它会为你完成大部分工作。
    【解决方案3】:

    我有一个类似的挑战,我想将宽度拉伸到屏幕的 100%,但保持宽度/高度比不变。所以我就这么做了。。

    创建一个扩展 ImageView 的 ScalableImageView 类:

    public class ScalableImageView extends ImageView {
        public boolean isMeasured = true; 
    
        public ScalableImageView(Context context) {
            super(context);
        }
    
        public ScalableImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ScalableImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            try
            {
                Drawable drawable = getDrawable();
    
                if (drawable == null)
                {
                    setMeasuredDimension(0, 0);
                }
                else
                {
                    int width = MeasureSpec.getSize(widthMeasureSpec);
                    int height = width * drawable.getIntrinsicHeight() / drawable.getIntrinsicWidth();
                    setMeasuredDimension(width, height);
                }
            }
            catch (Exception e)
            {
                isMeasured = false;
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    }
    

    在布局 XML 文件中,我为图像定义了一个占位符,如下所示:

    <ScalableImageView android:id="@+id/image1" 
        android:layout_centerHorizontal="true"
        android:src="@drawable/cam_image_placeholder" 
        android:scaleType="fitCenter" 
        android:layout_gravity="center_horizontal" 
        android:layout_height="wrap_content" 
        android:layout_width="match_parent" 
        android:adjustViewBounds="true"
        android:visibility="invisible" 
        android:layout_marginBottom="6px">
    </ScalableImageView>
    

    然后像这样加载/设置它:

    ScalableImageView imgView = null;
    imgView = (ScalableImageView)findViewById(imgViewResource);
    imgView.setImageDrawable(myDrawable);
    imgView.setVisibility(ScalableImageView.VISIBLE);
    

    【讨论】:

    • 这对我弄清楚如何仅使用一个维度进行缩放(缩放宽度或高度)并保持正确的比例非常有用。谢谢!
    • 很高兴它有帮助。享受吧。
    • 如果您以编程方式设置位图,这将不起作用。
    • 相反,您可以简单地使用 Imageview 并设置宽度以匹配父项和高度以包装内容,使用 scaletype "fitXY" 并将adjustViewbounds 设置为true。你会得到同样想要的效果。
    • @AmeyaB 哪个 android 版本可以使用,因为这是我尝试的第一件事,但它从未对我有用,就像你描述的那样。
    【解决方案4】:

    您可以使用Bitmap.createScaledBitmap(),但使用时请务必使用正确的转换公式:

    final float scale = getContext().getResources().getDisplayMetrics().density;
    int pixels = (int) (dps * scale + 0.5f);
    

    Bitmap.createScaledBitmap() 中,宽度和高度的单位是“像素”,而您应该始终按照here 的说明将尺寸设置为与密度无关的像素(dp 单位)。

    因此,如果您想显示保持密度独立的图像 - 即您的图像将占据任何设备上相同的屏幕部分 - 您需要使用类似于以下的代码:

    Bitmap b = decodeScaledFile(f);
    
    final float scale = mContext.getResources().getDisplayMetrics().density;
    int p = (int) (SIZE_DP * scale + 0.5f);
    
    Bitmap b2 = Bitmap.createScaledBitmap(b, p, p, true);
    

    【讨论】:

    • @LuxuryMode SIZE_DP 是与密度无关的像素中的图像大小 - 请参阅 here
    • 使用 createScaledBitmap 实际上会创建一个全新的位图,因此您将内存用于 2 个位图吗?例如,如果第一个位图占用 x 字节,那么缩放 2 的位图是否会占用原始的 2*2=4 倍,所以总共使用大约 4x+x=5x 字节?
    【解决方案5】:

    您可以根据此代码创建 scaledBitmap。

    private Bitmap getScaledBitMapBaseOnScreenSize(Bitmap bitmapOriginal){
    
        Bitmap scaledBitmap=null;
        try {
            DisplayMetrics metrics = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
    
    
            int width = bitmapOriginal.getWidth();
            int height = bitmapOriginal.getHeight();
    
            float scaleWidth = metrics.scaledDensity;
            float scaleHeight = metrics.scaledDensity;
    
            // create a matrix for the manipulation
            Matrix matrix = new Matrix();
            // resize the bit map
            matrix.postScale(scaleWidth, scaleHeight);
    
            // recreate the new Bitmap
            scaledBitmap = Bitmap.createBitmap(bitmapOriginal, 0, 0, width, height, matrix, true);
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return scaledBitmap;
    }
    

    方法调用&设置缩放图像为imageview

     Bitmap scaleBitmap=getScaledBitMapBaseOnScreenSize(originalBitmapImage);
        if(scaleBitmap!=null) {
        imageView.setImageBitmap(scaleBitmap);
        }
    

    我的 imageview xml 代码,

     <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:scaleType="center"
        />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多