如何在Android中制作自定义相机布局?

Posted

技术标签:

【中文标题】如何在Android中制作自定义相机布局?【英文标题】:How to make custom camera layout in Android? 【发布时间】:2018-06-04 13:19:33 【问题描述】:

我正在尝试开发某种具有文本识别功能的 OCR 应用程序。我编写并发现了一些正常工作的代码,但我的问题是我想在相机布局中进行一些自定义。我想添加我自己的捕获按钮并添加一个框架。我实际上是在另一个带有“表面视图/支架”的项目中做到的。但我无法实施我的项目,因为它的工作方式非常不同。

public class MainActivity extends AppCompatActivity 

private static final int REQUEST_GALLERY = 0;
private static final int REQUEST_CAMERA = 1;

private static final String TAG = MainActivity.class.getSimpleName();

private Uri imageUri;
private TextView detectedTextView;    // layouttaki text view

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

    findViewById(R.id.choose_from_gallery).setOnClickListener(new View.OnClickListener()    // galeriden resim seçme işlemi
        @Override
        public void onClick(View v) 
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(intent, REQUEST_GALLERY);
        
    );

    findViewById(R.id.take_a_photo).setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v)   // resim çekme işlemi

            String filename = System.currentTimeMillis() + ".jpg";

            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.TITLE, filename);
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
            imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

            Intent intent = new Intent();
            intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(intent, REQUEST_CAMERA);
        
    );

    detectedTextView = (TextView) findViewById(R.id.detected_text);
    detectedTextView.setMovementMethod(new ScrollingMovementMethod());


private void inspectFromBitmap(Bitmap bitmap)   //kendisine gelen bitmap resimden inspect yapar


    TextRecognizer textRecognizer = new TextRecognizer.Builder(this).build();
    try 
        if (!textRecognizer.isOperational()) 
            new AlertDialog.
                    Builder(this).
                    setMessage("Text recognizer could not be set up on your device").show();
            return;
        

        Frame frame = new Frame.Builder().setBitmap(bitmap).build();
        SparseArray<TextBlock> origTextBlocks = textRecognizer.detect(frame);
        List<TextBlock> textBlocks = new ArrayList<>();


        for (int i = 0; i < origTextBlocks.size(); i++) 
            TextBlock textBlock = origTextBlocks.valueAt(i);
            textBlocks.add(textBlock);
        
        Collections.sort(textBlocks, new Comparator<TextBlock>() 
            @Override
            public int compare(TextBlock o1, TextBlock o2) 
                int diffOfTops = o1.getBoundingBox().top - o2.getBoundingBox().top;
                int diffOfLefts = o1.getBoundingBox().left - o2.getBoundingBox().left;
                if (diffOfTops != 0) 
                    return diffOfTops;
                
                return diffOfLefts;
            
        );

        StringBuilder detectedText = new StringBuilder();
        for (TextBlock textBlock : textBlocks) 
            if (textBlock != null && textBlock.getValue() != null) 
                detectedText.append(textBlock.getValue());
                detectedText.append("\n");
            
        

        detectedTextView.setText(detectedText);     // detectedText is a final string
    
    finally 
        textRecognizer.release();
    




private void inspect(Uri uri) 
    InputStream is = null;
    Bitmap bitmap = null;
    try 
        is = getContentResolver().openInputStream(uri);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        options.inSampleSize = 2;
        options.inScreenDensity = DisplayMetrics.DENSITY_LOW;
        bitmap = BitmapFactory.decodeStream(is, null, options);

        Bitmap rotatedMap = RotateBitmap(bitmap,90);

        inspectFromBitmap(rotatedMap);
     catch (FileNotFoundException e) 
        Log.w(TAG, "Failed to find the file: " + uri, e);
     finally 
        if (bitmap != null) 
            bitmap.recycle();
        
        if (is != null) 
            try 
                is.close();
             catch (IOException e) 
                Log.w(TAG, "Failed to close InputStream", e);
            
        
    


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    switch (requestCode) 
        case REQUEST_GALLERY:
            if (resultCode == RESULT_OK) 
                inspect(data.getData());
            
            break;
        case REQUEST_CAMERA:
            if (resultCode == RESULT_OK) 
                if (imageUri != null) 
                    inspect(imageUri);
                
            
            break;
        default:
            super.onActivityResult(requestCode, resultCode, data);
            break;
    



public static Bitmap RotateBitmap(Bitmap source, float angle) // it rotates the bitmap for given parameter

    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);

在这种情况下,我该怎么办?谢谢各位。

【问题讨论】:

【参考方案1】:

不,您不能更改满足 ACTION_IMAGE_CAPTURE 意图的相机应用的布局。实际上,不同的设备不会有相同的相机应用程序。每一个都可能有非常不同的外观和感觉。您需要一个“自定义相机”来控制其布局和用户体验。

【讨论】:

以上是关于如何在Android中制作自定义相机布局?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android中自定义相机布局?

哪些第三方平台支持自定义相机应用程序?

具有自定义表面的 Android CameraX

如何使用实时贴纸制作自定义相机

在Android中绘制动态自定义视图棋盘

android制作自定义布局形状[关闭]