簡體   English   中英

android 中的裁剪圖像

[英]Crop image in android

我想對圖像進行裁剪,我發現了一些非常有用的圖像,但不知何故就像沒有使未選擇的區域變暗,所以我想知道有人知道怎么做嗎? 或引導我走向正確的方向? 我發現的在線教程顯示,它會使所選區域變暗,但是當我使用它時,它不會。 請幫助我,非常感謝,並為我的英語不好感到抱歉。

我使用的教程的鏈接。

裁剪圖像教程 1

裁剪圖像教程 2

我希望它是這樣的。

我希望它是這樣的

editButton.setOnClickListener(new Button.OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent goEdit;
            goEdit = new Intent(PreviewActivity.this, CropImage.class);
            goEdit.putExtra("image-path", path);
            goEdit.putExtra("scale", true);
            goEdit.putExtra("fileName", nameFromPath);
            //finish();
            checkEdit = true;
            startActivityForResult(goEdit,0);

        }
});

編輯我使用此按鈕偵聽器通過調用 class CropImage 活動來調用cropImage 文件。 這是一個自定義意圖,而不是 android 中的裁剪功能,但我認為它是它的副本,以便使其支持所有版本,但是當我調用它時,所選區域沒有變亮,我不知道問題出在哪里,誰能指導我? 謝謝 這是我正在使用的庫drioid4you 裁剪圖像

您可以使用默認的 android Crop 功能嗎?

這是我的代碼

private void performCrop(Uri picUri) {
    try {
        Intent cropIntent = new Intent("com.android.camera.action.CROP");
        // indicate image type and Uri
        cropIntent.setDataAndType(picUri, "image/*");
        // set crop properties here
        cropIntent.putExtra("crop", true);
        // indicate aspect of desired crop
        cropIntent.putExtra("aspectX", 1);
        cropIntent.putExtra("aspectY", 1);
        // indicate output X and Y
        cropIntent.putExtra("outputX", 128);
        cropIntent.putExtra("outputY", 128);
        // retrieve data on return
        cropIntent.putExtra("return-data", true);
        // start the activity - we handle returning in onActivityResult
        startActivityForResult(cropIntent, PIC_CROP);
    }
    // respond to users whose devices do not support the crop action
    catch (ActivityNotFoundException anfe) {
        // display an error message
        String errorMessage = "Whoops - your device doesn't support the crop action!";
        Toast toast = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
        toast.show();
    }
}

宣布:

final int PIC_CROP = 1;

在頂部。

在 onActivity 結果方法中,編寫以下代碼:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == PIC_CROP) {
        if (data != null) {
            // get the returned data
            Bundle extras = data.getExtras();
            // get the cropped bitmap
            Bitmap selectedBitmap = extras.getParcelable("data");

            imgView.setImageBitmap(selectedBitmap);
        }
    }
}

這對我來說很容易實現,並且還顯示了較暗的區域。

這個庫: Android-Image-Cropper對 CropImages 來說非常強大。 目前它在 github 上有 3,731 顆星。

您將使用幾行代碼裁剪圖像。

1 - 將依賴項添加到 buid.gradle (Module: app)

compile 'com.theartofdev.edmodo:android-image-cropper:2.7.+'

2 - 將權限添加到 AndroidManifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3 - 將 CropImageActivity 添加到 AndroidManifest.xml

<activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
 android:theme="@style/Base.Theme.AppCompat"/>

4 - 根據您的要求,從以下情況之一開始活動。

// start picker to get image for cropping and then use the image in cropping activity
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.start(this);

// start cropping activity for pre-acquired image saved on the device
CropImage.activity(imageUri)
.start(this);

// for fragment (DO NOT use `getActivity()`)
CropImage.activity()
.start(getContext(), this);

5 - 在 onActivityResult 中獲取結果

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
    CropImage.ActivityResult result = CropImage.getActivityResult(data);
    if (resultCode == RESULT_OK) {
      Uri resultUri = result.getUri();
    } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
      Exception error = result.getError();
    }
  }
}

您可以進行多種自定義,如將縱橫比或形狀設置為矩形、橢圓形等。

我做了一個非常酷的庫,試試這個。 這真的很流暢且易於使用。

https://github.com/TakuSemba/CropMe

希望你一切順利。 您可以使用我的代碼來裁剪圖像。您只需創建一個類並將該類用於您的XMljava類。 裁剪圖像 您可以將您選擇的圖像裁剪成圓形和方形,並有許多選項。 希望它對你有用。因為這對你來說是完全可以管理的,你可以根據你的需要改變它。

好好工作 :)

我最近剛剛為我自己的項目完成了這個。 請根據您的需要進行定制。 您也可以調整 4 個邊和 4 個角的大小。 我不擅長英語,但我盡力在代碼中添加注釋,請閱讀它們。 他們可能會有所幫助。

...

在此處輸入圖像描述

XML

     <your_package_name.CV4
            android:id="@+id/cv4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />

        <Button
            android:id="@+id/cropBtn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Crop"/>

        <ImageView
            android:id="@+id/croppedImage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

活動或片段中的代碼

cropBtn.setOnClickListener {
            val x = cv4.test()
            croppedImage.setImageBitmap(x)
        }

Mani 自定義查看代碼

package your.package.name  

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import com.voice.translator.app.speak.to.world.camerax.R
import kotlin.math.max
import kotlin.math.min


class CV4 @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

//    onMeasure will be called before onSizeChanged and onDraw
//    please see the View lifecycle for more details
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        screenWidth = MeasureSpec.getSize(widthMeasureSpec)
        imageWidth = screenWidth
        imageHeight = ((screenWidth.toFloat() / src.width) * src.height).toInt()
        setMeasuredDimension(screenWidth, imageHeight)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        val desiredWidthInPx = imageWidth
        val derivedHeightInPx = (desiredWidthInPx / aspectRatio).toInt()

        output = Bitmap.createScaledBitmap(src, desiredWidthInPx, derivedHeightInPx, true)
        rectF2 = RectF(0f, 0f, imageWidth.toFloat(), derivedHeightInPx.toFloat())
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)

        parent.requestDisallowInterceptTouchEvent(true)
        canvas?.apply {

            // background image under overlay
            drawBitmap(output, 0f, 0f, null)

            // dark overlay
            drawRect(rectF2, rectPaint2)

            // clip rect same as movable rect. This will hide everything outside
            clipRect(rectF)

            // visible clear image covered by clip rect
            drawBitmap(output, 0f, 0f, null)

            // movable rect
            drawRoundRect(rectF, 10f, 10f, rectPaint)
        }
    }


    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {

        if (event != null) {
            motionX = event.x
            motionY = event.y
            when (event.action) {
                MotionEvent.ACTION_MOVE -> moveMove()
                MotionEvent.ACTION_DOWN -> moveDown()
                MotionEvent.ACTION_UP -> moveUp()
            }
        }

        return true

    }

    private fun moveMove() {

        //moving the whole rect
        if (c5) {

            if (pr < screenWidth && motionX > plx) {
                pr = min(r + (motionX - plx), screenWidth.toFloat())
                pl = min(l + (motionX - plx), screenWidth.toFloat() - (r - l))
            }
            if (pl > 0 && motionX < plx) {
                pr = max(r - (plx - motionX), 0f + (r - l))
                pl = max(l - (plx - motionX), 0f)
            }
            if (pb < imageHeight && motionY > pty) {
                pb = min(b + (motionY - pty), imageHeight.toFloat())
                pt = min(t + (motionY - pty), imageHeight.toFloat() - (b - t))
            }
            if (pt > 0 && motionY < pty) {
                pb = max(b - (pty - motionY), 0f + (b - t))
                pt = max(t - (pty - motionY), 0f)
            }
            rectF.set(pl + 5, pt + 5, pr - 5, pb - 5)
            invalidate()
        }

        // moving while holding corners
        if (c6) {
            if (motionX > 0 && motionX < (pr - 100)) pl = motionX
            if (motionY > 0 && motionY < (pb - 100)) pt = motionY
        }
        if (c7) {
            if (motionY > 0 && motionY < (pb - 100)) pt = motionY
            if (motionX > (pl + 100) && motionX < screenWidth) pr = motionX
        }
        if (c8) {
            if (motionX > (pl + 100) && motionX < screenWidth) pr = motionX
            if (motionY > (pt + 100) && motionY < imageHeight) pb = motionY
        }
        if (c9) {
            if (motionX > 0 && motionX < (pr - 100)) pl = motionX
            if (motionY > (pt + 100) && motionY < imageHeight) pb = motionY
        }

        // For moving the edge
        if (c1) if (motionX > 0 && motionX < (pr - 100)) pl = motionX
        if (c2) if (motionY > 0 && motionY < (pb - 100)) pt = motionY
        if (c3) if (motionX > (pl + 100) && motionX < screenWidth) pr = motionX
        if (c4) if (motionY > (pt + 100) && motionY < imageHeight) pb = motionY


        rectF.set(pl + 5, pt + 5, pr - 5, pb - 5)
        invalidate()

    }

    private fun moveDown() {

        if (motionX > (pl + rng) && motionX < (pr - rng) && motionY > (pt + rng) && motionY < (pb - rng)) {

            c5 = true
            l = pl
            t = pt
            r = pr
            b = pb

            if (motionY >= 0 && motionY <= imageHeight) pty = motionY
            if (motionX >= 0 && motionX <= screenWidth) plx = motionX

            invalidate()
            return
        }

        if (motionX in pl - rng..pl + rng && motionY in pt - rng..pt + rng) {
            c6 = true
            invalidate()
            return
        }
        if (motionY in pt - rng..pt + rng && motionX in pr - rng..pr + rng) {
            c7 = true
            invalidate()
            return
        }
        if (motionX in pr - rng..pr + rng && motionY in pb - rng..pb + rng) {
            c8 = true
            invalidate()
            return
        }
        if (motionY in pb - rng..pb + rng && motionX in pl - rng..pl + rng) {
            c9 = true
            invalidate()
            return
        }




        if (motionX > (pl - rng) && motionX < (pl + rng) && motionY > pt && motionY < pb) {
            c1 = true
            invalidate()
            return
        }
        if (motionY > (pt - rng) && motionY < (pt + rng) && motionX > pl && motionX < pr) {
            c2 = true
            invalidate()
            return
        }
        if (motionX > (pr - rng) && motionX < (pr + rng) && motionY > pt && motionY < pb) {
            c3 = true
            invalidate()
            return
        }
        if (motionY > (pb - rng) && motionY < (pb + rng) && motionX > pl && motionX < pr) {
            c4 = true
            invalidate()
            return
        }


        invalidate()

    }

    private fun moveUp() {
        c1 = false
        c2 = false
        c3 = false
        c4 = false
        c5 = false

        c6 = false
        c7 = false
        c8 = false
        c9 = false

        invalidate()
    }


    // pass bitmap image
    private val src: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.mountain)

    private var screenWidth = 0
    private var imageWidth = 0
    private var imageHeight = 0
    private val aspectRatio: Float = src.width / src.height.toFloat()

    //get the bitmap from test():Bitmap? function
    private lateinit var output: Bitmap

    fun test(): Bitmap? {

        val cropWidth: Float = (pr - pl)
        val cropHeight: Float = (pb - pt)

        invalidate()
        //returning the bitmap
        return Bitmap.createBitmap(
            output,
            pl.toInt(),
            pt.toInt(),
            cropWidth.toInt(),
            cropHeight.toInt()
        )
    }


    private var motionX = 0f
    private var motionY = 0f
    private var rng = 40f // Touch range for the 4 side and 4 corners of the rect

    // p for point and l=left t=top r=right b=bottom
    private var pl = 100f
    private var plx = 100f //hold motionX value from moveDown() function

    private var pt = 100f
    private var pty = 100f //hold motionY value from moveDown() function

    private var pr = 300f
    private var pb = 400f

    //hold left,top,right,bottom value from moveDown() function
    private var l = 0f
    private var t = 0f
    private var r = 0f
    private var b = 0f

    // check user touch Down on rect edges, corners or inside

    //edges point
    private var c1 = false
    private var c2 = false
    private var c3 = false
    private var c4 = false

    private var c5 = false  // for inside selection to move the whole rect

    //corners point
    private var c6 = false
    private var c7 = false
    private var c8 = false
    private var c9 = false


    // resizable rect
    private var rectF = RectF(pl + 5, pt + 5, pr - 5, pb - 5)
    private val rectPaint = Paint().apply {
        style = Paint.Style.STROKE
        strokeWidth = 10f
        color = Color.YELLOW

    }

    // dark overlay rect
    private val foregroundArcColor =
        context.resources?.getColor(R.color.custom3, null) ?: Color.GRAY
    private var rectF2 = RectF(0f, 0f, screenWidth.toFloat(), imageHeight.toFloat())
    private val rectPaint2 = Paint().apply {
        style = Paint.Style.FILL
        color = foregroundArcColor
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM