如何在圆角方块中拟合位图?

时间:2018-05-19 13:05:16

标签: android imageview android-bitmap aspect-ratio

我正在使用Android Studio,我希望能够从图库中拾取图像,调整大小并通过保持正确的宽高比使其适合圆角正方形(约300x300像素)。 目前,我可以调整大小并将其显示为圆圈。

 FixBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                bitmap_to_save = scaleBitmapAndKeepRation(FixBitmap, 320, 320);

                RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap_to_save);
                roundDrawable.setCircular(true);
                p_avatar.setImageDrawable(roundDrawable);

但是,我想知道是否可以使位图看起来像我的附加图像。此外,在不丢失原始宽高比的情况下调整图像大小非常重要。

enter image description here

这不完全是一个方形的圆形图,所以我不确定是否可以在Android中执行此操作。

请记住,我根据用户操作在dinamycally中更改代码内的imageview。因此,这不是静态图像,如果用户上传新图像,我会用新图像替换原始内容。

20月5日编辑1

这是我的imageview" avatar":

的XML代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="loginpackage.social.com.ui.profile.ProfileActivity">

    <include layout="@layout/custom_toolbar_shadow" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_horizontal"
            android:orientation="vertical"
            android:paddingTop="@dimen/_20sdp">


            <ImageView
                android:id="@+id/avatar"
                android:layout_width="137dp"
                android:layout_height="150dp"
                android:layout_gravity="center"
                android:clickable="true"
                android:paddingBottom="@dimen/_10sdp"
                android:paddingTop="@dimen/_10sdp"
                />


            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/_20sdp"
                android:orientation="vertical"
                android:paddingLeft="@dimen/_16sdp"
                android:paddingRight="@dimen/_16sdp">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/profileActivity_name"
                    android:textSize="@dimen/_14sdp" />

                <EditText
                    android:id="@+id/et_fullname"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_5sdp"
                    android:background="@color/colorWhite"
                    android:hint="@string/signActivity_fullname"
                    android:imeOptions="actionDone"
                    android:inputType="textNoSuggestions"
                    android:maxLines="1"
                    android:padding="@dimen/_10sdp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_10sdp"
                    android:text="@string/profileActivity_email"
                    android:textSize="@dimen/_14sdp" />

                <EditText
                    android:id="@+id/et_email"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_5sdp"
                    android:background="@drawable/editext_back_login"
                    android:hint="@string/mainActivity_email"
                    android:imeOptions="actionNext"
                    android:inputType="textEmailAddress|textNoSuggestions"
                    android:maxLines="1"
                    android:padding="@dimen/_10sdp" />

                <Button
                    android:id="@+id/btn_update"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:background="@color/colorSignuoBtn"
                    android:text="@string/profileActivity_update"
                    android:textColor="@color/colorWhite"
                    android:textSize="@dimen/_12sdp"
                    android:visibility="invisible" />

                <TextView
                    android:id="@+id/txt_logout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginBottom="@dimen/_10sdp"
                    android:layout_marginTop="@dimen/_20sdp"
                    android:background="@drawable/button_logout_profile"
                    android:foreground="?attr/selectableItemBackgroundBorderless"
                    android:gravity="center"
                    android:paddingBottom="@dimen/_12sdp"
                    android:paddingTop="@dimen/_12sdp"
                    android:text="@string/profileActivity_logout"
                    android:textSize="@dimen/_12sdp" />
            </LinearLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

编辑2

目前,我正在使用毕加索来渲染图像,它似乎运作良好。 问题是我想始终保持相同的图片尺寸(350x350px)和宽高比。怎么可能这样做?

 Transformation transformation = new RoundedTransformationBuilder()
                    .borderColor(Color.GREEN)
                    .borderWidthDp(2)
                    .cornerRadiusDp(15)
                    .oval(false)
                    .build();

            Picasso.get().load("http://www.server.com/uploads/avatars/"+Conts.USERINFO.getId()).transform(transformation).memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE).networkPolicy(NetworkPolicy.NO_CACHE) .into(p_avatar);

EDIT3:

 <com.makeramen.roundedimageview.RoundedImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/avatar"
            android:layout_width="160dp"
            android:layout_height="160dp"
            android:src="@drawable/adduserprofile"
            android:scaleType="centerCrop"
            app:riv_border_width="2dip"
            app:riv_border_color="#333333"
            app:riv_mutate_background="true"
            app:riv_oval="false"
            app:riv_corner_radius_bottom_left="20dp"
            app:riv_corner_radius_top_right="20dp"
            />

为什么我为riv_corner_radius_top_right设置了不同的值,然后应用程序崩溃了? 例如,如果我设置:

 app:riv_corner_radius_bottom_left="20dp"
 app:riv_corner_radius_top_right="10dp"

我收到此错误:

  E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: loginpackage.social.com, PID: 25495
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{loginpackage.social.com/loginpackage.social.com.ui.profile.ProfileActivity}: android.view.InflateException: Binary XML file line #24: Error inflating class com.makeramen.roundedimageview.RoundedImageView
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2689)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754)
                      at android.app.ActivityThread.access$900(ActivityThread.java:177)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:145)
                      at android.app.ActivityThread.main(ActivityThread.java:5938)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:372)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
                   Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class com.makeramen.roundedimageview.RoundedImageView
                      at android.view.LayoutInflater.createView(LayoutInflater.java:640)
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:511)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
                      at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
                      at loginpackage.social.com.ui.profile.ProfileActivity.onCreate(ProfileActivity.java:93)
                      at android.app.Activity.performCreate(Activity.java:6288)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2642)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:177) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:145) 
                      at android.app.ActivityThread.main(ActivityThread.java:5938) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:372) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 
                   Caused by: java.lang.reflect.InvocationTargetException
                      at java.lang.reflect.Constructor.newInstance(Native Method)
                      at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
                      at android.view.LayoutInflater.createView(LayoutInflater.java:614)
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:511) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:415) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:366) 
                      at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287) 
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139) 
                      at loginpackage.social.com.ui.profile.ProfileActivity.onCreate(ProfileActivity.java:93) 
                      at android.app.Activity.performCreate(Activity.java:6288) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2642) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:177) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:145) 
                      at android.app.ActivityThread.main(ActivityThread.java:5938) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:372) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 
                   Caused by: java.lang.IllegalArgumentException: Multiple nonzero corner radii not yet supported.
                      at com.makeramen.roundedimageview.RoundedDrawable.setCornerRadius(RoundedDrawable.java:507)
                      at com.makeramen.roundedimageview.RoundedImageView.updateAttrs(RoundedImageView.java:368)
                      at com.makeramen.roundedimageview.RoundedImageView.updateDrawableAttrs(RoundedImageView.java:318)
                      at com.makeramen.roundedimageview.RoundedImageView.<init>(RoundedImageView.java:163)
                      at com.makeramen.roundedimageview.RoundedImageView.<init>(RoundedImageView.java:86)
                      at java.lang.reflect.Constructor.newInstance(Native Method) 
                      at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
                      at android.view.LayoutInflater.createView(LayoutInflater.java:614) 
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:813) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:821) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:511) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:415) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:366) 
                      at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287) 
                      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139) 
                      at loginpackage.social.com.ui.profile.ProfileActivity.onCreate(ProfileActivity.java:93) 
                      at android.app.Activity.performCreate(Activity.java:6288) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2642) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:177) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:145) 
                      at android.app.ActivityThread.main(ActivityThread.java:5938) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:372) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 

2 个答案:

答案 0 :(得分:1)

如果您正在公司工作,则不应该花时间管理这些类型的逻辑。

相反,您可以使用已经完成了大量工作的库。 见https://github.com/vinc3m1/RoundedImageView

你的ImageView就像

<com.makeramen.roundedimageview.RoundedImageView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/imageView1"
        android:src="@drawable/photo1"
        android:scaleType="centerCrop"
        app:riv_corner_radius="30dip"
        app:riv_border_width="2dip"
        app:riv_border_color="#333333"
        app:riv_mutate_background="true"
        app:riv_tile_mode="repeat"
        app:riv_oval="true" />

和依赖

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.makeramen:roundedimageview:2.3.0'
}

<强>更新

你似乎对android很新,如果你不理解id和src,不用担心!

  

基本上id是您创建的唯一ID,您可以参考   imageView1,如果你在java代码中找到了ViewById(R.id.imageView1)。

有关id:Difference between "@id/" and "@+id/" in Android

的更多信息
  

src是该图像的源图像文件,位于drawables目录中。

关于您的问题

您可以使用符合您要求的不同ImageView ScaleType。 我认为你在imageView使用适合你图像的android:scaleType="centerCrop"

我还在上面的答案中编辑了scaleType。如果这不符合您的要求,您可以使用其中任何scale type

更新2 以设置宽度和高度,您可以设置layout_widthlayout_height属性。如下。

 <com.makeramen.roundedimageview.RoundedImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/imageView1"
            android:src="@drawable/photo1"
            android:scaleType="centerCrop"
            app:riv_corner_radius="30dip"
            app:riv_border_width="2dip"
            app:riv_border_color="#333333"
            app:riv_mutate_background="true"
            app:riv_tile_mode="repeat"
            app:riv_oval="true" 
            android:layout_width="350dp"
            android:layout_height="350dp"/>

请参阅What is the difference between "px", "dip", "dp" and "sp"?以获取有关android中的sp,dp,px的更多详细信息。

答案 1 :(得分:1)

我写了一个MaskView,可以让你将图像蒙版成任何形状,包括中间的洞和部分透明度。这是很多代码,我很久以前就写过这样的代码,所以如果不仔细检查就不会自己使用它。但它的本质是ImageView采用alpha蒙版。当它自己绘制时,它会为自己及其背后的任何内容绘制两个位图,并使用蒙版将它们组合在一起。

enter image description here