Android - не только выровнять, но и обрезать изображение с помощью setPolyToPoly () - PullRequest
0 голосов
/ 26 ноября 2018

Цель состоит в том, чтобы преобразовать четырехугольную область (заданную 4 точками) изображения в прямоугольное изображение.С Matrix.setPolyToPoly() и Bitmap.createBitmap() я могу выровнять целое изображение так, чтобы точки образовывали прямоугольник, но теперь я не знаю, где находится его левый верхний угол, поэтому я не могу его обрезать.

Например, скажем, 4 точки - это углы флага (цвет чирка - это просто фон ImageView) :

example

Вот код с жестко запрограммированными значениями, чтобы установить флажок для растрового изображения 72x48.

int w = 72;
int h = 48;
float src[] = {108, 201,
               532, 26,
               554, 301,
               55,  372};
float dst[] = {0, 0,
               w, 0,
               w, h,
               0, h};
Matrix m = new Matrix();
m.setPolyToPoly(src, 0, dst, 0, dst.length >> 1);

Bitmap b1 = BitmapFactory.decodeResource(getResources(), R.drawable.img);
ImageView iv1 = findViewById(R.id.testImg1);
iv1.setImageBitmap(b1);

Bitmap b2 = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight(), m, true);
ImageView iv2 = findViewById(R.id.testImg2);
iv2.setImageBitmap(b2);

//these coordinates are hand-picked
Bitmap b3 = Bitmap.createBitmap(b2, 132, 208, w, h);
ImageView iv3 = findViewById(R.id.testImg3);
iv3.setImageBitmap(b3);

И оригинальное изображение (не забудьте сохранить его в res / drawable-nodpi):

original image

1 Ответ

0 голосов
/ 30 ноября 2018

Поскольку @pskink не опубликовал свой ответ, я делаю это.

Создать новый Bitmap и сохранить оригинальный - это именно то, что мне нужно, поэтому вот решение для меня:

int w = 72;
int h = 48;
float srcPoints[] = {108, 201,
                         532, 26,
                         554, 301,
                         55,  372};
float dstPoints[] = {0, 0,
                     w, 0,
                     w, h,
                     0, h};
Matrix m = new Matrix();
m.setPolyToPoly(srcPoints, 0, dstPoints, 0, dstPoints.length >> 1);
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.macedonia);
Bitmap dstBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(dstBitmap);
canvas.clipRect(0, 0, w, h);
canvas.drawBitmap(srcBitmap, m, null);

Но если вы не хотите использовать дополнительную память, используйте другой подход:

class BD extends BitmapDrawable {
    Matrix matrix = new Matrix();
    int w = 72;
    int h = 48;
    RectF clip = new RectF(0, 0, w, h);

    public BD(Resources res, int resId) {
        super(res, BitmapFactory.decodeResource(res, resId));
        float src[] = {108,201,532,26,554,301,55,372};
        float dst[] = {0,0,w,0,w,h,0,h};
        matrix.setPolyToPoly(src, 0, dst, 0, src.length / 2);
    }

    @Override public int getIntrinsicWidth() {return w;}
    @Override public int getIntrinsicHeight() {return h;}

    @Override
    public void draw(Canvas canvas) {
        canvas.clipRect(clip);
        canvas.drawBitmap(getBitmap(), matrix, null);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...