2017-01-04 4 views
3

У меня есть приложение для камеры, которые имеют центрированный вид прямоугольника, как вы можете увидеть ниже:Android Пользовательские камеры - Обрезка изображения внутри прямоугольника

Camera Screenshot

Когда я беру картину, которую я хочу, чтобы игнорировать все снаружи прямоугольник. Вид не имеет никакой связи с камерой предварительного просмотра или SurfaceView на мой взгляд XML следующим образом:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"> 
<FrameLayout 
    android:id="@+id/preview" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <SurfaceView 
     android:id="@+id/cameraview" 
     android:name="com.kut.camera.KutCameraFragment" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" /> 

    <View android:id="@+id/viewTamanho" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_marginBottom="400px" 
     android:layout_marginTop="300px" 
     android:layout_marginStart="70px" 
     android:layout_marginEnd="70px" 
     android:background="@drawable/border" /> 

    <RelativeLayout 
     android:id="@+id/rel_layout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" > 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:alpha="1" 
      android:background="@android:color/black" 
      android:orientation="vertical" 
      android:padding="10dp" > 

      <RelativeLayout 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" > 

       <TextView 
        android:id="@+id/textViewReferan" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_centerHorizontal="true" 
        android:layout_centerVertical="true" 
        android:text="Evidência" 
        android:textColor="@android:color/white" 
        android:textSize="16sp" /> 

       <Button 
        android:id="@+id/button_exit" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_alignParentEnd="true" 
        android:layout_alignParentRight="true" 
        android:layout_alignParentTop="true" 
        android:background="@android:color/transparent" 
        android:text="Sair" 
        android:textColor="#2799CF" /> 
      </RelativeLayout> 

      <LinearLayout 
       android:id="@+id/progress_layout" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_gravity="center" 
       android:gravity="center" 
       android:orientation="vertical" 
       android:visibility="gone" > 

       <ProgressBar 
        android:id="@+id/progressBar1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" /> 

       <TextView 
        android:id="@+id/islem_value_textView" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Carregando..." /> 

      </LinearLayout> 
     </LinearLayout> 

     <RelativeLayout 
      android:id="@+id/RelativeLayout1" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignParentBottom="true" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentStart="true" 
      android:alpha="0.9" 
      android:background="@android:color/black" 
      android:padding="10dp" > 

      <ImageView 
       android:id="@+id/imageView_foto" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_centerHorizontal="true" 
       android:layout_centerVertical="true" 
       android:src="@drawable/camera" /> 

      <ImageView 
       android:id="@+id/imageView_photo" 
       android:layout_width="80dp" 
       android:layout_height="100dp" 
       android:layout_alignParentLeft="true" 
       android:layout_alignParentStart="true" 
       android:layout_centerVertical="true" 
       android:layout_marginRight="5dp" 
       android:layout_marginEnd="5dp" 
       android:padding="5dp" 
       android:scaleType="fitCenter" 
       android:src="@drawable/fotoicon" /> 
     </RelativeLayout> 
    </RelativeLayout> 
</FrameLayout> 

Может кто-нибудь помочь мне, как обрезать изображение правильно? Я пытался создать новый Bitmap на основе моего XML, но, очевидно, она не работает, что-то вроде:

Camera.PictureCallback jpegCallback = new Camera.PictureCallback() { 
    public void onPictureTaken(byte[] data, Camera camera) { 
     //.../ 
     Bitmap imagemOriginal = BitmapFactory.decodeByteArray(data, 0, data.length); 
     Bitmap imagemCortada = Bitmap.createBitmap(imagemOriginal, 70, 400, imagemOriginal.getWidth() - 70, 
       imagemOriginal.getHeight() - 400); 
     //.../ 
    } 

Я ставлю эти начальные значения для х и у, и пытался вычитать (на основе значений XML из поля зрения ссылаясь на marginTop, Bottom и т. д.) из ширины и высоты, но у меня не было успеха, потому что я не знаю, как совместить View координат с координатами изображения, взятыми из Camera. Кроме того, мне кажется, что Bitmap.createBitmap делает ограниченный урожай, по-видимому, я не могу обрезать его прямо на прямоугольник.

+1

Что именно не сработало? Основная проблема с вашим кодом заключается в том, что исходное растровое изображение может быть огромным, и ваше приложение может не работать. Возможно, вы не правильно настроили камеру, особенно не назовете 'setPictureSize()' правильно. –

+0

Я сказал, что не знаю, как правильно обрезать его, чтобы соответствовать координатам прямоугольника. Вы видите в битмапе.createBitmap Я поместил начальные значения для x и y и попытаюсь вычесть значения из ширины и высоты, но я не могу определить правильные значения. Я просто помещаю эти значения там, потому что это то, что я положил из marginTop, marginBottom в XML. Кроме того, как я могу узнать, какие правильные значения для * setPictureSize() *, если размеры экрана варьируются. –

+1

tehere is croping ui library https://android-arsenal.com/details/1/207 chk it out, если вы можете использовать его ... или вдохнуть –

ответ

3

Для управления обрезкой вы должны контролировать размер изображения и размер прямоугольника.

Это очень важно а) выбрать размер изображения с соотношением сторон, как предварительный просмотр, и б) убедитесь, что предварительный просмотр не искажается на экране. Если вы готовите приложение для широкого спектра устройств, обе задачи не являются тривиальными. Для достижения последнего вам необходимо контролировать размер предварительного просмотра и размер SurfaceView. Я объяснил это более подробно elsewhere.

Чтобы это было просто, я предлагаю игнорировать таблетки, которые могут иметь естественную ландшафтную ориентацию. На телефонах снятое изображение будет «повернуто» 90 °, даже если вы настроили ориентацию камеры на портрет (это только предварительный просмотр эффектов). Не ожидайте, что setRotation() исправить это для вас: по книге, можно просто установить флаг EXIF ​​для захваченного изображения.

Вы установите поля для viewTamanho в пикс. Это может плохо масштабироваться на разных экранах. Я предлагаю установить размеры этого представления программно, как определенный процент поверхности предварительного просмотра. Вы можете использовать support library, чтобы определить это в XML, но я боюсь, что это не даст вам достаточного контроля.

Со всем этим под рукой предположим, что у нас есть предварительный просмотр 1280 × 720, изображение 2560 × 1440, наш экран 1280 × 800, а прямоугольник находится посередине, 616 × 400 пикселей (что больше или меньше размер, масштабированный от вашего снимка экрана).

Фактический размер предварительного просмотра на экране будет, вероятно, 1000x562, дополнен справа и слева черными полями 79px. Затем следующий код произведет ожидаемое снятое изображение:

public void onPictureTaken(byte[] data, Camera camera) { 
    //.../ 
    Bitmap imagemOriginal = BitmapFactory.decodeByteArray(data, 0, data.length); // 2560×1440 
    float scale = 1280/1000.; 
    int left = scale*(imagemOriginal.getWidth()-400)/2; 
    int top = scale*(imagemOriginal.getHeight()-616)/2; 
    int width = scale*400; 
    int height = scale*616; 
    Matrix rotationMatrix = new Matrix(); 
    rotationMatrix.postRotate(90); 
    Bitmap imagemCortada = Bitmap.createBitmap(imagemOriginal, left, top, width, height, rotationMatrix, false); 
    //.../ 
}