0

I am new to Java and Android, so please have mercy. I have 3 buttons and imageView in my activity. Each button generates new version of the picture displayed in ImageView. I would like the imageView to enlarge the current picture to full screen when I click on it. My question is: What would be the best approach to achieve this?

  1. Should I create onClickListener to enlarge the picture?
  2. Should I define a method for ImageView to call in activity_start.xml like android:onClick="myMethodToCall

    My activity_start.xml code:

    <Button
        android:id="@+id/button1"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:onClick="template1match"
        android:text="image1" />
    
    <Button
        android:id="@+id/button2"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/button1"
        android:layout_centerHorizontal="true"
        android:onClick="template2match"
        android:text="image2" />
    
    <Button
        android:id="@+id/button3"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@+id/button2"
        android:layout_marginRight="16dp"
        android:onClick="template3match"
        android:text="image3" />
    
    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:clickable="true"
        android:src="@drawable/wall" />
    

My Start.java code:

package com.example.matchtemplate;

import java.io.File;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.Core.MinMaxLocResult;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class Start extends Activity {

    Button button1;
    Button button2;
    Button button3;

    ImageView imageView1;

    File cacheDir;

    protected static final String TAG = "OpenCV";

    private BaseLoaderCallback mLoaderCallBack = new BaseLoaderCallback(this) {
        public void onManagerConnected(int status) {
            switch (status) {
            case LoaderCallbackInterface.SUCCESS:
                Log.i(TAG, "Open CV loaded successfully");
                break;

            default:
                super.onManagerConnected(status);
                break;
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
        //addListenerOnButton();
        initDir();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.start, menu);
        return true;
    }

    @Override
    public void onResume() {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this,
                mLoaderCallBack);

    }

    // ADDED THIS: to create/initialize external file
    // Be sure write permissions is enabled in the manifest file
    // ie add: <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE"/>
    public void initDir() {
        if (android.os.Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED)) {
            cacheDir = new File(
                    android.os.Environment.getExternalStorageDirectory(),
                    "FileList");

            if (!cacheDir.exists()) {
                cacheDir.mkdirs();
            }
        }
    }

    // added this to simplify creating full file path
    public String getFileAbsPath(String fileName) {
        File f = new File(cacheDir, fileName);
        return f.getAbsolutePath();
    }

    public void template1match(View v) {

        imageView1 = (ImageView) findViewById(R.id.imageView1);
        button1 = (Button) findViewById(R.id.button1);

        String infile = getFileAbsPath("wall.jpg");
        String tp = getFileAbsPath("template1.jpg");
        String outFile = getFileAbsPath("result.jpg");

        try {
            matchTemplate(infile, tp, outFile, Imgproc.TM_CCOEFF);
            Bitmap bm = BitmapFactory.decodeFile(outFile);
            imageView1.setImageBitmap(bm);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

    public void template2match(View v) {

        imageView1 = (ImageView) findViewById(R.id.imageView1);
        button2 = (Button) findViewById(R.id.button2);

        String infile = getFileAbsPath("wall.jpg");
        String tp = getFileAbsPath("template2.jpg");
        String outFile = getFileAbsPath("result.jpg");

        try {
            matchTemplate(infile, tp, outFile, Imgproc.TM_CCOEFF);
            Bitmap bm = BitmapFactory.decodeFile(outFile);
            imageView1.setImageBitmap(bm);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

    public void template3match(View v) {

    imageView1 = (ImageView) findViewById(R.id.imageView1);
    button3 = (Button) findViewById(R.id.button3);

    String infile = getFileAbsPath("wall.jpg");
    String tp = getFileAbsPath("template3.jpg");
    String outFile = getFileAbsPath("result.jpg");

    try {
        matchTemplate(infile, tp, outFile, Imgproc.TM_CCOEFF);
        Bitmap bm = BitmapFactory.decodeFile(outFile);
        imageView1.setImageBitmap(bm);
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }
}


    public void matchTemplate(String inFile, String templateFile,
            String outFile, int match_method) {
        Log.i(TAG, "Running Template Matching");

        Mat img = Highgui.imread(inFile);
        Mat templ = Highgui.imread(templateFile);

        // / Create the result matrix
        int result_cols = img.cols() - templ.cols() + 1;
        int result_rows = img.rows() - templ.rows() + 1;
        Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);

        // / Do the Matching and Normalize
        Imgproc.matchTemplate(img, templ, result, match_method);
        Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

        // / Localizing the best match with minMaxLoc
        MinMaxLocResult mmr = Core.minMaxLoc(result);

        Point matchLoc;
        if (match_method == Imgproc.TM_SQDIFF
                || match_method == Imgproc.TM_SQDIFF_NORMED) {
            matchLoc = mmr.minLoc;
        } else {
            matchLoc = mmr.maxLoc;
        }

        // / Show me what you got
        Core.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
                matchLoc.y + templ.rows()), new Scalar(0, 255, 0));

        // Save the visualized detection.
        Log.i(TAG, "Writing: " + outFile);
        Highgui.imwrite(outFile, img);

    }
}
jaspernorth
  • 415
  • 1
  • 10
  • 28

3 Answers3

0

The two are equivalent- all that happens with the xml is that behind the scenes Android will create an onClickListener for you, register it, and that listener will call the function named in the xml. So there's no real reason to prefer one over the other. Since there's no reason to care, I tend to go the xml route as it requires slightly less code.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • Thanks for clarification. Do you know what code should I use to display the picture in full screen? – jaspernorth Jul 14 '13 at 19:11
  • There's a couple ways to do it. One would be to launch a new activity that does nothing but show the picture fullscreen. Another way would be to have an ImageView set to fill the entire screen but have it invisible. When you want to show it, just change its visibility to VISIBLE and it will appear on top of the rest of your UI. – Gabe Sechan Jul 14 '13 at 19:14
  • Have a look at [this](http://stackoverflow.com/questions/6410364/how-to-scale-bitmap-to-screen-size) question. I suggest just launching a new Activity that only has a full screen imageview inside, and display the image in that imageview – Jade Byfield Jul 14 '13 at 19:14
0

i saw the Gabe's answer.But i will have my own answer.Both are same despite in case of xml Android will take care of creating the onClicListener for you.But i will prefer to go for coding rather than xml as it will be easier to understand.Suppose someone will see your code tomorrow and will click the image and image will enlarge, he will not the onClicklistener in the code so may get confuse at his first look.Though if he will be a good coder he will look for xml,but if it will be there in the code itself then it will be easier to understand.

Android Killer
  • 18,174
  • 13
  • 67
  • 90
  • Decent point. My main dislike for the code way of doing it is that if you have lots of listeners to hook up it just becomes a huge mass of boilerplate that makes your onCreate function difficult to read. I do suggest that if you use xml you name the function appropriately- something like nameOfButtonClicked – Gabe Sechan Jul 14 '13 at 19:20
  • @GabeSechan Agreed!!! but in that case we can implement the OnClickListener in the activity itself and override the onClick(View v) method and we can use a switch case to compare id and do the corresponding opretation. – Android Killer Jul 14 '13 at 19:23
0

if I was in your place I would implement an alert dialogue once the image is clicked, and in the alert dialogue there is a custom .xml which has a fill_parent imageview. So once the image is clicked the alert comes and the image inside becomes the image clicked

John Jared
  • 790
  • 3
  • 16
  • 40