Rabu, 16 Juli 2014

Aplikasi Android Image Zoom In, Zoom Out, Gambar pada ImageView Pinch Zoom Dua Jari Geser Satu Jari, Klik Coordinate Pixel


Aplikasi Android Image Zoom In, Zoom Out, Gambar pada ImageView Pinch Zoom Dua Jari Geser Satu Jari, Klik Coordinate Pixel sering kita lihat pada aplikasi yang menampilkan Gambar, Foto atau Image. Fitur Zoom (Perbesar) maupun Drag (Geser) sudah lazim dibutuhkan oleh pengguna ketika melihat suatu Image / Gambar di Layar Perangkat Mobile. Zoom In (Perbesar) dan Zoom Out (Perkecil) biasanya dilakukan dengan menggeser dua buah jari secara bersamaan menjauh atau mendekat. Sedangkan drag (Geser) dilakukan dengan satu jari.

Disamping itu kita juga akan mencoba mempelajari cara memperoleh koordinat gambar yang absolut ketika kita klik suatu gambar. Hal ini bisa dimanfaatkan untuk membuat Peta atau Denah Sederhana. Atau media pembelajaran Bergambar.

Pertama buat dahulu project Android di Eclipse :

Kemudian pada MainActivity.java tidak perlu diubah seperti berikut ini :

package com.amijaya.imageview_pinch_zoom_in_out; import android.os.Bundle; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.FloatMath; import android.util.Log; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends Activity { // nuramijaya@gmail.com // http://cariprogram.blogspot.com // http://contohprogram.com // These matrices will be used to move and zoom image Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); // We can be in one of these 3 states static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; String savedItemClicked; ImageView imageView1; String TAG = "DEBUG"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView1 = (ImageView)findViewById(R.id.imageView1); imageView1.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub ImageView view = (ImageView) v; dumpEvent(event); // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG"); mode = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; Log.d(TAG, "mode=ZOOM"); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: if ((event.getX() == start.x) && (event.getY() == start.y)) { //KHUSUS UNTUK KLIK (TOUCH SAJA) TANPA DRAG ATAU ZOOM //Toast.makeText(getApplicationContext(), "TOUCH", Toast.LENGTH_SHORT).show(); float eventX = event.getX(); float eventY = event.getY(); float[] eventXY = new float[] {eventX, eventY}; Matrix invertMatrix = new Matrix(); ((ImageView)imageView1).getImageMatrix().invert(invertMatrix); invertMatrix.mapPoints(eventXY); int px = Integer.valueOf((int)eventXY[0]); int py = Integer.valueOf((int)eventXY[1]); //touchedXY.setText( // "touched position: " // + String.valueOf(eventX) + " / " // + String.valueOf(eventY)); //invertedXY.setText( // "touched position: " // + String.valueOf(x) + " / " // + String.valueOf(y)); Drawable imgDrawable = ((ImageView)imageView1).getDrawable(); Bitmap bitmap = ((BitmapDrawable)imgDrawable).getBitmap(); //imgSize.setText( // "drawable size: " // + String.valueOf(bitmap.getWidth()) + " / " // + String.valueOf(bitmap.getHeight())); //Limit x, y range within bitmap if(px < 0){ px = 0; }else if(px > bitmap.getWidth()-1){ px = bitmap.getWidth()-1; } if(py < 0){ py = 0; }else if(py > bitmap.getHeight()-1){ py = bitmap.getHeight()-1; } //double pxx = (px / bitmap.getWidth()) * 100; //double pyy = (py / bitmap.getHeight()) * 100; double pxx = (px * 100); double pww = bitmap.getWidth(); pxx = pxx / pww; double pyy = (py * 100); double phh = bitmap.getWidth(); pyy = pyy / phh; Toast.makeText(getApplicationContext(), "TOUCH- " + pxx + " : " + pyy, Toast.LENGTH_SHORT).show(); } mode = NONE; Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float newDist = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } } break; } view.setImageMatrix(matrix); return true; } }); } private void dumpEvent(MotionEvent event) { String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; StringBuilder sb = new StringBuilder(); int action = event.getAction(); int actionCode = action & MotionEvent.ACTION_MASK; sb.append("event ACTION_").append(names[actionCode]); if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) { sb.append("(pid ").append( action >> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append(")"); } sb.append("["); for (int i = 0; i < event.getPointerCount(); i++) { sb.append("#").append(i); sb.append("(pid ").append(event.getPointerId(i)); sb.append(")=").append((int) event.getX(i)); sb.append(",").append((int) event.getY(i)); if (i + 1 < event.getPointerCount()) sb.append(";"); } sb.append("]"); Log.d(TAG, sb.toString()); } /** Determine the space between the first two fingers */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** Calculate the mid point of the first two fingers */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }

Untuk tampilan, buat desain tampilan berikut ini pada activity_main.xml, tambahkan satu buah ImageView, seperti di bawah ini :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <!-- ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="matrix"
        android:src="@drawable/nexus7" /-->
    
    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="15dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:layout_marginTop="15dp"
        android:src="@drawable/nexus7"
        android:scaleType="matrix" />

</LinearLayout>

Konfigurasi AndroidManifest.xml tidak perlu dirubah :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.amijaya.imageview_pinch_zoom_in_out"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.amijaya.imageview_pinch_zoom_in_out.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Jangan lupa menambahkan gambar JPG atau PNG ke folder project bagian res/drawable. Jika kita tidak mau menambahkan gambar, bisa dilgunakan icon ic_launcher.png yang disertakan oleh Eclipse. Anda juga bisa menggunakan gambar yang ada pada project yang disertakan di artikel ini.

Hasilnya setelah dijalankan muncul gambar di layar, kemudian cobalah untuk Menggeser Gambar (Drag) dengan satu jari. Kemudian coba pula untuk memperbesar Gambar dengan cara Pinch (Menekan dengan dua jari kemudian kedua jari digeser saling menjauhi. Atau Memperkecil gambar dengan cara yang sama tetapi kedua jari digeser saling mendekati.


Fitur terakhir adalah ketika diklik dengan satu jari tanpa digeser, kita dapatkan koordinat Absolut pixel di layar (X dan Y). Hal ini bisa dimanfaatkan untuk membuat Denah atau Peta sederhana, disamping itu juga dapat digunakan untuk membuat Aplikasi Media Pembelajaran Bergambar, yaitu ketika diklik suatu bagian gambar bisa kita keluarkan Keterangan Gambar tersebut.


File project selengkapnya dapat anda download disini. Jika kesulitan cara download, silakan lihat caranya disini.

Semoga bermanfaat ^_^

2 komentar:

  1. gan,, klo hanya zoom in sama zoom out gimana yah???

    BalasHapus
  2. Pas! Makasih suhuuu. Ohiya kalo buat zoom in sama zoom outnya aja gimana tuh gan?

    BalasHapus