在应用程序中的圆形图像视图中显示FB轮廓图片

时间:2014-05-05 04:17:48

标签: android facebook facebook-graph-api bitmap

我正在尝试从FB获取用户的个人资料照片并将其显示在我的应用程序上的圆形图像中。我能够检索并显示Facebook SDK提供的ProfilePictureView小部件中的显示图片。但是当我尝试获取该图像的位图并尝试将其置于圆形图像视图中时,我得到了默认的FB显示图片,如果您没有显示图片,则每个人都会被分配。我无法解决这个问题。我这样做是为了从ProfilePictureView中取出位图并将其设置为我的圆形视图。

if (session == Session.getActiveSession()) {
                if (user != null) {

                    // Set the id for the ProfilePictureView
                    // view that in turn displays the profile picture.

                    profilePictureView.setDrawingCacheEnabled(true);
                    profilePictureView.setProfileId(user.getId());



                    Bitmap bitmap = profilePictureView.getDrawingCache();


                        Bitmap circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);

                        BitmapShader shader = new BitmapShader (bitmap,  TileMode.CLAMP, TileMode.CLAMP);
                        Paint paint = new Paint();
                        paint.setShader(shader);
                        Canvas c = new Canvas(circleBitmap);
                     c.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, bitmap.getWidth()/2, paint);

                        profilePic.setImageBitmap(circleBitmap);
                     //profilePictureView.draw(c);
                     //c.drawCircle(bitmap.getWidth()/2, bitmap.getHeight()/2, bitmap.getWidth()/2, paint);

}

这里profilePic是我试图放置圆形的ImageView,而profilePictureView是具有显示pic的ProfilePictureView id。

7 个答案:

答案 0 :(得分:36)

我从facebok ProfilePictureView中获取代码并对其进行了一些修改:

以下是代码:

package com.myapp.mypackage.view;

/**
 * Copyright 2010-present Facebook.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.facebook.FacebookException;
import com.facebook.LoggingBehavior;
import com.facebook.android.R;
import com.facebook.internal.ImageDownloader;
import com.facebook.internal.ImageRequest;
import com.facebook.internal.ImageResponse;
import com.facebook.internal.Logger;
import com.facebook.internal.Utility;

import java.net.URISyntaxException;

/**
 * View that displays the profile photo of a supplied profile ID, while conforming
 * to user specified dimensions.
 */
public class ProfilePictureView extends FrameLayout {

    /**
     * Callback interface that will be called when a network or other error is encountered
     * while retrieving profile pictures.
     */
    public interface OnErrorListener {
        /**
         * Called when a network or other error is encountered.
         *
         * @param error a FacebookException representing the error that was encountered.
         */
        void onError(FacebookException error);
    }

    /**
     * Tag used when logging calls are made by ProfilePictureView
     */
    public static final String TAG = ProfilePictureView.class.getSimpleName();

    /**
     * Indicates that the specific size of the View will be set via layout params.
     * ProfilePictureView will default to NORMAL X NORMAL, if the layout params set on
     * this instance do not have a fixed size.
     * Used in calls to setPresetSize() and getPresetSize().
     * Corresponds with the preset_size Xml attribute that can be set on ProfilePictureView.
     */
    public static final int CUSTOM = -1;

    /**
     * Indicates that the profile image should fit in a SMALL X SMALL space, regardless
     * of whether the cropped or un-cropped version is chosen.
     * Used in calls to setPresetSize() and getPresetSize().
     * Corresponds with the preset_size Xml attribute that can be set on ProfilePictureView.
     */
    public static final int SMALL = -2;

    /**
     * Indicates that the profile image should fit in a NORMAL X NORMAL space, regardless
     * of whether the cropped or un-cropped version is chosen.
     * Used in calls to setPresetSize() and getPresetSize().
     * Corresponds with the preset_size Xml attribute that can be set on ProfilePictureView.
     */
    public static final int NORMAL = -3;

    /**
     * Indicates that the profile image should fit in a LARGE X LARGE space, regardless
     * of whether the cropped or un-cropped version is chosen.
     * Used in calls to setPresetSize() and getPresetSize().
     * Corresponds with the preset_size Xml attribute that can be set on ProfilePictureView.
     */
    public static final int LARGE = -4;

    private static final int MIN_SIZE = 1;
    private static final boolean IS_CROPPED_DEFAULT_VALUE = true;
    private static final String SUPER_STATE_KEY = "ProfilePictureView_superState";
    private static final String PROFILE_ID_KEY = "ProfilePictureView_profileId";
    private static final String PRESET_SIZE_KEY = "ProfilePictureView_presetSize";
    private static final String IS_CROPPED_KEY = "ProfilePictureView_isCropped";
    private static final String BITMAP_KEY = "ProfilePictureView_bitmap";
    private static final String BITMAP_WIDTH_KEY = "ProfilePictureView_width";
    private static final String BITMAP_HEIGHT_KEY = "ProfilePictureView_height";
    private static final String PENDING_REFRESH_KEY = "ProfilePictureView_refresh";

    private String profileId;
    private int queryHeight = ImageRequest.UNSPECIFIED_DIMENSION;
    private int queryWidth = ImageRequest.UNSPECIFIED_DIMENSION;
    private boolean isCropped = IS_CROPPED_DEFAULT_VALUE;
    private Bitmap imageContents;
    private ImageView image;
    private int presetSizeType = CUSTOM;
    private ImageRequest lastRequest;
    private OnErrorListener onErrorListener;
    private Bitmap customizedDefaultProfilePicture = null;

    /**
     * Constructor
     *
     * @param context Context for this View
     */
    public ProfilePictureView(Context context) {
        super(context);
        initialize(context);
    }

    /**
     * Constructor
     *
     * @param context Context for this View
     * @param attrs   AttributeSet for this View.
     *                The attribute 'preset_size' is processed here
     */
    public ProfilePictureView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context);
        parseAttributes(attrs);
    }

    /**
     * Constructor
     *
     * @param context  Context for this View
     * @param attrs    AttributeSet for this View.
     *                 The attribute 'preset_size' is processed here
     * @param defStyle Default style for this View
     */
    public ProfilePictureView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialize(context);
        parseAttributes(attrs);
    }

    /**
     * Gets the current preset size type
     *
     * @return The current preset size type, if set; CUSTOM if not
     */
    public final int getPresetSize() {
        return presetSizeType;
    }

    /**
     * Apply a preset size to this profile photo
     *
     * @param sizeType The size type to apply: SMALL, NORMAL or LARGE
     */
    public final void setPresetSize(int sizeType) {
        switch (sizeType) {
            case SMALL:
            case NORMAL:
            case LARGE:
            case CUSTOM:
                this.presetSizeType = sizeType;
                break;

            default:
                throw new IllegalArgumentException("Must use a predefined preset size");
        }

        requestLayout();
    }

    /**
     * Indicates whether the cropped version of the profile photo has been chosen
     *
     * @return True if the cropped version is chosen, false if not.
     */
    public final boolean isCropped() {
        return isCropped;
    }

    /**
     * Sets the profile photo to be the cropped version, or the original version
     *
     * @param showCroppedVersion True to select the cropped version
     *                           False to select the standard version
     */
    public final void setCropped(boolean showCroppedVersion) {
        isCropped = showCroppedVersion;
        // No need to force the refresh since we will catch the change in required dimensions
        refreshImage(false);
    }

    /**
     * Returns the profile Id for the current profile photo
     *
     * @return The profile Id
     */
    public final String getProfileId() {
        return profileId;
    }

    /**
     * Sets the profile Id for this profile photo
     *
     * @param profileId The profileId
     *                  NULL/Empty String will show the blank profile photo
     */
    public final void setProfileId(String profileId) {
        boolean force = false;
        if (Utility.isNullOrEmpty(this.profileId) || !this.profileId.equalsIgnoreCase(profileId)) {
            // Clear out the old profilePicture before requesting for the new one.
            setBlankProfilePicture();
            force = true;
        }

        this.profileId = profileId;
        refreshImage(force);
    }

    /**
     * Returns the current OnErrorListener for this instance of ProfilePictureView
     *
     * @return The OnErrorListener
     */
    public final OnErrorListener getOnErrorListener() {
        return onErrorListener;
    }

    /**
     * Sets an OnErrorListener for this instance of ProfilePictureView to call into when
     * certain exceptions occur.
     *
     * @param onErrorListener The Listener object to set
     */
    public final void setOnErrorListener(OnErrorListener onErrorListener) {
        this.onErrorListener = onErrorListener;
    }

    /**
     * The ProfilePictureView will display the provided image while the specified
     * profile is being loaded, or if the specified profile is not available.
     *
     * @param inputBitmap The bitmap to render until the actual profile is loaded.
     */
    public final void setDefaultProfilePicture(Bitmap inputBitmap) {
        customizedDefaultProfilePicture = inputBitmap;
    }

    /**
     * Overriding onMeasure to handle the case where WRAP_CONTENT might be
     * specified in the layout. Since we don't know the dimensions of the profile
     * photo, we need to handle this case specifically.
     * <p/>
     * The approach is to default to a NORMAL sized amount of space in the case that
     * a preset size is not specified. This logic is applied to both width and height
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        ViewGroup.LayoutParams params = getLayoutParams();
        boolean customMeasure = false;
        int newHeight = MeasureSpec.getSize(heightMeasureSpec);
        int newWidth = MeasureSpec.getSize(widthMeasureSpec);
        if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY &&
                params.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
            newHeight = getPresetSizeInPixels(true); // Default to a preset size
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY);
            customMeasure = true;
        }

        if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY &&
                params.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
            newWidth = getPresetSizeInPixels(true); // Default to a preset size
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
            customMeasure = true;
        }

        if (customMeasure) {
            // Since we are providing custom dimensions, we need to handle the measure
            // phase from here
            setMeasuredDimension(newWidth, newHeight);
            measureChildren(widthMeasureSpec, heightMeasureSpec);
        } else {
            // Rely on FrameLayout to do the right thing
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    /**
     * In addition to calling super.Layout(), we also attempt to get a new image that
     * is properly size for the layout dimensions
     */
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        // See if the image needs redrawing
        refreshImage(false);
    }

    /**
     * Some of the current state is returned as a Bundle to allow quick restoration
     * of the ProfilePictureView object in scenarios like orientation changes.
     *
     * @return a Parcelable containing the current state
     */
    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        Bundle instanceState = new Bundle();
        instanceState.putParcelable(SUPER_STATE_KEY, superState);
        instanceState.putString(PROFILE_ID_KEY, profileId);
        instanceState.putInt(PRESET_SIZE_KEY, presetSizeType);
        instanceState.putBoolean(IS_CROPPED_KEY, isCropped);
        instanceState.putParcelable(BITMAP_KEY, imageContents);
        instanceState.putInt(BITMAP_WIDTH_KEY, queryWidth);
        instanceState.putInt(BITMAP_HEIGHT_KEY, queryHeight);
        instanceState.putBoolean(PENDING_REFRESH_KEY, lastRequest != null);

        return instanceState;
    }

    /**
     * If the passed in state is a Bundle, an attempt is made to restore from it.
     *
     * @param state a Parcelable containing the current state
     */
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state.getClass() != Bundle.class) {
            super.onRestoreInstanceState(state);
        } else {
            Bundle instanceState = (Bundle) state;
            super.onRestoreInstanceState(instanceState.getParcelable(SUPER_STATE_KEY));

            profileId = instanceState.getString(PROFILE_ID_KEY);
            presetSizeType = instanceState.getInt(PRESET_SIZE_KEY);
            isCropped = instanceState.getBoolean(IS_CROPPED_KEY);
            queryWidth = instanceState.getInt(BITMAP_WIDTH_KEY);
            queryHeight = instanceState.getInt(BITMAP_HEIGHT_KEY);

            setImageBitmap((Bitmap) instanceState.getParcelable(BITMAP_KEY));

            if (instanceState.getBoolean(PENDING_REFRESH_KEY)) {
                refreshImage(true);
            }
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        // Null out lastRequest. This way, when the response is returned, we can ascertain
        // that the view is detached and hence should not attempt to update its contents.
        lastRequest = null;
    }

    private void initialize(Context context) {
        // We only want our ImageView in here. Nothing else is permitted
        removeAllViews();

        image = new ImageView(context);

        LayoutParams imageLayout = new LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT);

        image.setLayoutParams(imageLayout);

        // We want to prevent up-scaling the image, but still have it fit within
        // the layout bounds as best as possible.
        image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        addView(image);
    }

    private void parseAttributes(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.com_facebook_profile_picture_view);
        setPresetSize(a.getInt(R.styleable.com_facebook_profile_picture_view_preset_size, CUSTOM));
        isCropped = a.getBoolean(R.styleable.com_facebook_profile_picture_view_is_cropped, IS_CROPPED_DEFAULT_VALUE);
        a.recycle();
    }

    private void refreshImage(boolean force) {
        boolean changed = updateImageQueryParameters();
        // Note: do not use Utility.isNullOrEmpty here as this will cause the Eclipse
        // Graphical Layout editor to fail in some cases
        if (profileId == null || profileId.length() == 0 ||
                ((queryWidth == ImageRequest.UNSPECIFIED_DIMENSION) &&
                        (queryHeight == ImageRequest.UNSPECIFIED_DIMENSION))) {
            setBlankProfilePicture();
        } else if (changed || force) {
            sendImageRequest(true);
        }
    }

    private void setBlankProfilePicture() {
        if (customizedDefaultProfilePicture == null) {
            int blankImageResource = isCropped() ?
                    R.drawable.com_facebook_profile_picture_blank_square :
                    R.drawable.com_facebook_profile_picture_blank_portrait;
            setImageBitmap(BitmapFactory.decodeResource(getResources(), blankImageResource));
        } else {
            // Update profile image dimensions.
            updateImageQueryParameters();
            // Resize inputBitmap to new dimensions of queryWidth and queryHeight.
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(customizedDefaultProfilePicture, queryWidth, queryHeight, false);
            setImageBitmap(scaledBitmap);
        }
    }

    private void setImageBitmap(Bitmap imageBitmap) {
        if (image != null && imageBitmap != null) {
            imageContents = imageBitmap; // Hold for save-restore cycles
            image.setImageBitmap(ProfilePictureView.getRoundedBitmap(imageBitmap));
        }
    }

    private void sendImageRequest(boolean allowCachedResponse) {
        try {
            ImageRequest.Builder requestBuilder = new ImageRequest.Builder(
                    getContext(),
                    ImageRequest.getProfilePictureUrl(profileId, queryWidth, queryHeight));

            ImageRequest request = requestBuilder.setAllowCachedRedirects(allowCachedResponse)
                    .setCallerTag(this)
                    .setCallback(
                            new ImageRequest.Callback() {
                                @Override
                                public void onCompleted(ImageResponse response) {
                                    processResponse(response);
                                }
                            }
                    )
                    .build();

            // Make sure to cancel the old request before sending the new one to prevent
            // accidental cancellation of the new request. This could happen if the URL and
            // caller tag stayed the same.
            if (lastRequest != null) {
                ImageDownloader.cancelRequest(lastRequest);
            }
            lastRequest = request;

            ImageDownloader.downloadAsync(request);
        } catch (URISyntaxException e) {
            Logger.log(LoggingBehavior.REQUESTS, Log.ERROR, TAG, e.toString());
        }
    }

    private void processResponse(ImageResponse response) {
        // First check if the response is for the right request. We may have:
        // 1. Sent a new request, thus super-ceding this one.
        // 2. Detached this view, in which case the response should be discarded.
        if (response.getRequest() == lastRequest) {
            lastRequest = null;
            Bitmap responseImage = response.getBitmap();
            Exception error = response.getError();
            if (error != null) {
                OnErrorListener listener = onErrorListener;
                if (listener != null) {
                    listener.onError(new FacebookException(
                            "Error in downloading profile picture for profileId: " + getProfileId(), error));
                } else {
                    Logger.log(LoggingBehavior.REQUESTS, Log.ERROR, TAG, error.toString());
                }
            } else if (responseImage != null) {
                setImageBitmap(responseImage);

                if (response.isCachedRedirect()) {
                    sendImageRequest(false);
                }
            }
        }
    }

    private boolean updateImageQueryParameters() {
        int newHeightPx = getHeight();
        int newWidthPx = getWidth();
        if (newWidthPx < MIN_SIZE || newHeightPx < MIN_SIZE) {
            // Not enough space laid out for this View yet. Or something else is awry.
            return false;
        }

        int presetSize = getPresetSizeInPixels(false);
        if (presetSize != ImageRequest.UNSPECIFIED_DIMENSION) {
            newWidthPx = presetSize;
            newHeightPx = presetSize;
        }

        // The cropped version is square
        // If full version is desired, then only one dimension is required.
        if (newWidthPx <= newHeightPx) {
            newHeightPx = isCropped() ? newWidthPx : ImageRequest.UNSPECIFIED_DIMENSION;
        } else {
            newWidthPx = isCropped() ? newHeightPx : ImageRequest.UNSPECIFIED_DIMENSION;
        }

        boolean changed = (newWidthPx != queryWidth) || (newHeightPx != queryHeight);

        queryWidth = newWidthPx;
        queryHeight = newHeightPx;

        return changed;
    }

    private int getPresetSizeInPixels(boolean forcePreset) {
        int dimensionId;
        switch (presetSizeType) {
            case SMALL:
                dimensionId = R.dimen.com_facebook_profilepictureview_preset_size_small;
                break;
            case NORMAL:
                dimensionId = R.dimen.com_facebook_profilepictureview_preset_size_normal;
                break;
            case LARGE:
                dimensionId = R.dimen.com_facebook_profilepictureview_preset_size_large;
                break;
            case CUSTOM:
                if (!forcePreset) {
                    return ImageRequest.UNSPECIFIED_DIMENSION;
                } else {
                    dimensionId = R.dimen.com_facebook_profilepictureview_preset_size_normal;
                    break;
                }
            default:
                return ImageRequest.UNSPECIFIED_DIMENSION;
        }

        return getResources().getDimensionPixelSize(dimensionId);
    }

    public static Bitmap getRoundedBitmap(Bitmap bitmap) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawOval(rectF, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
}

在底部你可以看到一个新方法:getRoundedBitmap

答案 1 :(得分:7)

如此处所述:FrameLayout, Your Best UI Friend您可以使用FrameLayout将任何可绘制的内容放在图片上方。特别是,您可以在ProfilePictureView上放置图像或SVG路径(API级别21及以上)。

例如,您可以使用以下布局:

{2}

以下SVG路径表示带有减去圆的矩形:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true">

    <com.facebook.login.widget.ProfilePictureView
        android:id="@+id/profile_picture"
        android:layout_width="160dp"
        android:layout_height="160dp"></com.facebook.login.widget.ProfilePictureView>

    <ImageView
        android:id="@+id/android"
        android:layout_width="160dp"
        android:layout_height="160dp"
        android:src="@drawable/subtracted_circle"
        android:contentDescription="@null" />

</FrameLayout>

你会得到这样的东西:

enter image description here

答案 2 :(得分:2)

您可以使用FrameLayout方法将gusridd答案与某些PNG文件(中间的透明度)相匹配。而不是使用向量(API +21), drawable / subtracted_circle 将是res / drawable / subtracted_circle.png中的文件。 即使你很难生成这个文件,你也可以使用你想要的任何形状。 您还需要在图片中使用相同颜色的背景。

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">

<com.facebook.login.widget.ProfilePictureView
    android:id="@+id/profile_picture"
    android:layout_width="160dp"
    android:layout_height="160dp"></com.facebook.login.widget.ProfilePictureView>

<ImageView
    android:id="@+id/android"
    android:layout_width="160dp"
    android:layout_height="160dp"
    android:src="@drawable/subtracted_circle"
    android:contentDescription="@null" />

 </FrameLayout>

res/drawable/subtracted_circle.png

答案 3 :(得分:1)

我在这里找到了一个有用的工作代码。希望能帮助到你。 http://curious-blog.blogspot.in/2014/05/create-circle-bitmap-in-android.html

<强> activity_main.xml中

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@android:color/darker_gray"
    tools:context="com.example.circlebitmaptest.MainActivity" >

    <ImageView 
        android:id="@+id/image"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="fitXY"/>

    </LinearLayout>

getCircleBitmap函数

    private Bitmap getCircleBitmap(Bitmap bitmap) {
    final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
    bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(output);

 final int color = Color.RED;
 final Paint paint = new Paint();
 final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
 final RectF rectF = new RectF(rect);

 paint.setAntiAlias(true);
 canvas.drawARGB(0, 0, 0, 0);
 paint.setColor(color);
 canvas.drawOval(rectF, paint);

 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
 canvas.drawBitmap(bitmap, rect, rect, paint);

 bitmap.recycle();

 return output;
}

MainActivity Class

  @Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 // create bitmap from resource
 Bitmap bm = BitmapFactory.decodeResource(getResources(),
  R.drawable.simple_image);

 // set circle bitmap
 ImageView mImage = (ImageView) findViewById(R.id.image);
 mImage.setImageBitmap(getCircleBitmap(bm));

}

答案 4 :(得分:1)

我花了很多时间研究显示圆形Facebook个人资料图片的选项,我认为将Android SDK放在一边并且只利用现有图像库的转换是最容易的。

使用ProfilePictureView而不是使用Facebook ImageView。然后,使用Picasso,Glide或您喜欢的任何库加载图像。下面我使用Picasso和Picasso-Transformations。

现在:

ImageView profilePic = (ImageView) findViewById(R.id.ivProfilePic);

Picasso.with(this)
     .load("https://graph.facebook.com/v2.2/" + user.getUserId() + "/picture?height=120&type=normal") //extract as User instance method
     .transform(new CropCircleTransformation())
     .resize(120, 120)
     .into(profilePic);

之前:

ProfilePictureView profilePic = (ProfilePictureView)findViewById(R.id.ivProfilePic);
profilePic.setProfileId(user.getUserId());
//custom transformation code

答案 5 :(得分:0)

我在PHP中的解决方案是:

http://pastebin.com/RNthU2Pg

答案 6 :(得分:-1)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:facebook="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:gravity="center_horizontal"
    android:orientation="horizontal" >
<com.facebook.widget.ProfilePictureView
        android:id="@+id/welcome_profile_pic"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        facebook:preset_size="small" />
<TextView
        android:id="@+id/welcome_user_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_gravity="center"
        android:textColor="#333"
        android:textSize="18sp" />


<Button 
    android:id="@+id/bHomeScreen"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="Go To Home Screen"
    android:textSize="24sp"
    />
</LinearLayout>