web-dev-qa-db-fra.com

Recadrer l'image carrée pour encercler - par programme

je cherchais depuis un jour et je n'ai pas réussi.

je reçois l'image de l'API et je la télécharge dans un fichier bitmap à l'aide du code suivant.

private Bitmap DownloadImage(String URL) 
    {
        Bitmap bitmap = null;
        InputStream in = null;
        try 
        {
            in = OpenHttpConnection(URL);
            bitmap = BitmapFactory.decodeStream(in);
            in.close();
        }
        catch (IOException e1) 
        {
            e1.printStackTrace();
        }
        return bitmap;
    }

    private InputStream OpenHttpConnection(String urlString) throws IOException 
    {
        InputStream in = null;
        int response = -1;

        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();

        if (!(conn instanceof HttpURLConnection))
            throw new IOException("Not an HTTP connection");

        try 
        {
            HttpURLConnection httpConn = (HttpURLConnection) conn;
            httpConn.setAllowUserInteraction(false);
            httpConn.setInstanceFollowRedirects(true);
            httpConn.setRequestMethod("GET");
            httpConn.connect();

            response = httpConn.getResponseCode();
            if (response == HttpURLConnection.HTTP_OK) 
            {
                in = httpConn.getInputStream();
            }
        }
        catch (Exception ex) 
        {
            throw new IOException("Error connecting");
        }
        return in;
    }

Et je reçois l'image comme un carré et je veux recadrer les quatre coins et en faire une image circulaire. Y a-t-il un moyen possible de réaliser?

Toutes les réponses liées sont les bienvenues. Merci d'avance .

20
VIGNESH
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        DrawingView dv = new DrawingView(this);
        setContentView(dv);
    }

    class DrawingView extends View {
        Bitmap bitmap;

        public DrawingView(Context context) {
            super(context);
            bitmap = BitmapFactory.decodeResource(context.getResources(),
                    R.drawable.glossy_overlay);

        }

        @Override
        public void onDraw(Canvas canvas) {
            Paint paint = new Paint();
            // Paint.setColor(Color.CYAN);
            canvas.drawBitmap(getclip(), 30, 20, Paint);
        }

        public Bitmap getclip() {
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                    bitmap.getHeight(), 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());

            Paint.setAntiAlias(true);
            canvas.drawARGB(0, 0, 0, 0);
            // Paint.setColor(color);
            canvas.drawCircle(bitmap.getWidth() / 2,
                    bitmap.getHeight() / 2, bitmap.getWidth() / 2, Paint);
            Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
            canvas.drawBitmap(bitmap, rect, rect, Paint);
            return output;
        }
    }
}
20
Raghunandan

Une fois le bitmap récupéré RoundedBitmapDrawableFactory peut être utilisé pour générer un RoundedBitmapDrawable à partir de v4 Support Library . Cette Drawable peut ensuite être appliquée à une ImageView ou directement dessinée à une Canvas.

// Create the RoundedBitmapDrawable.
RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
roundDrawable.setCircular(true);

// Apply it to an ImageView.
ImageView imageView = (ImageView)findViewById(R.id.imageView);
imageView.setImageDrawable(roundDrawable);

// Alternatively, draw it to an canvas (e.g. in onDraw where a Canvas is available).
// setBounds since there's no View handling size and positioning.
roundDrawable.setBounds(left, top, right, bottom);
roundDrawable.draw(canvas);
17
Godfrey Duke

utilisez la fonction blow pour dessiner un cercle sur un bitmap, puis définissez le bitmap encerclé sur imageview

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

    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

    Paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
            bitmap.getWidth() / 2, Paint);
    Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, Paint);
    return output;
}
14
actsai

Roman Nurik propose une utilisation très directe des shaders pour faire des choses comme ça, avec un dessin personnalisable. 

Je change un peu le code pour créer une image ovale et me teste moi-même. L'effet et la performance sont vraiment bons:

public  class StreamDrawable extends Drawable {
private static final boolean USE_VIGNETTE = true;

private final RectF mRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private final int mMargin;

public StreamDrawable(Bitmap bitmap, int margin) {

    mBitmapShader = new BitmapShader(bitmap,
            Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setShader(mBitmapShader);

    mMargin = margin;
}

@Override
protected void onBoundsChange(Rect bounds) {
    super.onBoundsChange(bounds);
    mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin);

    if (USE_VIGNETTE) {
        RadialGradient vignette = new RadialGradient(
                mRect.centerX(), mRect.centerY() * 1.0f / 0.7f, mRect.centerX() * 1.3f,
                new int[] { 0, 0, 0x7f000000 }, new float[] { 0.0f, 0.7f, 1.0f },
                Shader.TileMode.CLAMP);

        Matrix oval = new Matrix();
        oval.setScale(1.0f, 0.7f);
        vignette.setLocalMatrix(oval);

        mPaint.setShader(
                new ComposeShader(mBitmapShader, vignette, PorterDuff.Mode.SRC_OVER));
    }
}

@Override
public void draw(Canvas canvas) {
    canvas.drawOval(mRect, mPaint);
}

@Override
public int getOpacity() {
    return PixelFormat.TRANSLUCENT;
}

@Override
public void setAlpha(int alpha) {
    mPaint.setAlpha(alpha);
}

@Override
public void setColorFilter(ColorFilter cf) {
    mPaint.setColorFilter(cf);
}
}
2
Renascienza

Cela peut être fait simplement en xml, veuillez consulter ma réponse ici: https://stackoverflow.com/a/18287979/665930

<RelativeLayout
            Android:id="@+id/icon_layout"
            Android:layout_width="@dimen/icon_mask"
            Android:layout_height="@dimen/icon_mask"
            Android:layout_alignParentLeft="true"
            Android:layout_alignParentTop="true" >

            <ImageView
                Android:id="@+id/icon"
                Android:layout_width="@dimen/icon"
                Android:layout_height="@dimen/icon"
                Android:layout_centerInParent="true"
                Android:scaleType="fitXY" >
            </ImageView>

            <ImageView
                Android:id="@+id/icon_mask"
                Android:layout_width="@dimen/icon_mask"
                Android:layout_height="@dimen/icon_mask"
                Android:layout_centerInParent="true"
                Android:background="@drawable/circle"
                Android:scaleType="fitXY" >
            </ImageView>


 </RelativeLayout>


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="oval" >
    <gradient Android:startColor="#00FFFFFF" Android:endColor="#00FFFFFF"
        Android:angle="270"/>
     <stroke Android:width="10dp" Android:color="#FFAAAAAA"/>
0
Ash

J'ai essayé les solutions ci-dessus mais aucune n'a bien fonctionné pour moi. En effet, la caméra de mon téléphone ne prend pas d'image carrée mais juste des images rectangle. Alors, j'apporte quelques modifications à la solution @actsai pour toujours prendre la dimension mineure puis rogner l'image en cercle:

public static Bitmap getBitmapClip(Bitmap bitmap) {
    int maxLenth = bitmap.getWidth() <= bitmap.getHeight() ? bitmap.getWidth() : bitmap.getHeight();
    Bitmap output = Bitmap.createBitmap(maxLenth,
            maxLenth, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, maxLenth, maxLenth);

    Paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    canvas.drawCircle(maxLenth / 2, maxLenth / 2,
            maxLenth / 2, Paint);
    Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, Paint);
    return output;
}

J'ai utilisé la propriété scale suivante pour remplir mon ImageView avec le nouveau bitmap:

<ImageView
    Android:id="@+id/iv_photo"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_gravity="center"
    Android:scaleType="fitXY" />
0
Ângelo Polotto