带有可点击区域的图像

时间:2013-10-23 09:01:07

标签: java android memory android-image

我创建了一个国家/地区的地图,当我点击每个区域时,我想要突出显示该区域。有17个地区,可以选择任何组合。为此,我将所有图像设置为不可见,除了背景国家地图,然后在用户单击关联区域时将每个图像设置为可见。

当我一次加载多个图像时,使用的内存量接近120mb。如何减少使用的内存量并仍能解决同样的问题?

每张图片仅约30kb。

我修改了here

中的代码
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * Created by Sam Murtagh on 23/10/13.
 */


public class MetActivity extends Activity
        implements View.OnTouchListener {

    static Integer colorFN = Color.rgb(0, 0, 255);
    static Integer colorTA = Color.rgb(255, 0, 0);
    static Integer colorED = Color.rgb(255, 255, 0);
    static Integer colorTK = Color.rgb(0, 255, 0);
    static Integer colorCP = Color.rgb(0, 255, 255);
    static Integer colorMH = Color.rgb(255, 0, 255);
    static Integer colorSA = Color.rgb(0, 166, 81);
    static Integer colorDV = Color.rgb(255, 255, 255);
    static Integer colorTN = Color.rgb(0, 174, 240);
    static Integer colorST = Color.rgb(247, 151, 121);
    static Integer colorWW = Color.rgb(83, 71, 65);
    static Integer colorKA = Color.rgb(189, 140, 191);
    static Integer colorAL = Color.rgb(96, 57, 19);
    static Integer colorPL = Color.rgb(0, 54, 99);
    static Integer colorFD = Color.rgb(125, 167, 217);
    static Integer colorCY = Color.rgb(172, 212, 115);
    static Integer colorGE = Color.rgb(75, 0, 73);

    private String metflightCode = null;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_met);

        ImageView iv = (ImageView) findViewById(R.id.image);
        if (iv != null) {
            iv.setOnTouchListener(this);
        }
    }

    public boolean onTouch(View v, MotionEvent ev) {
        boolean handledHere = false;

        final int action = ev.getAction();

        final int evX = (int) ev.getX();
        final int evY = (int) ev.getY();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                int touchColor = getHotspotColor(R.id.image_areas, evX, evY);
                int tolerance = 25;

                ImageView imageView2 = null;
                String arforCode = null;

                if (closeMatch(colorFN, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_fn);
                    arforCode = "FN";
                } else if (closeMatch(colorTA, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_ta);
                    arforCode = "TA";
                } else if (closeMatch(colorED, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_ed);
                    arforCode = "ED";
                } else if (closeMatch(colorTK, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_tk);
                    arforCode = "TK";
                } else if (closeMatch(colorCP, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_cp);
                    arforCode = "CP";
                } else if (closeMatch(colorMH, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_mh);
                    arforCode = "MH";
                } else if (closeMatch(colorSA, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_sa);
                    arforCode = "SA";
                } else if (closeMatch(colorDV, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_dv);
                    arforCode = "DV";
                } else if (closeMatch(colorTN, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_tn);
                    arforCode = "TN";
                } else if (closeMatch(colorST, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_st);
                    arforCode = "ST";
                } else if (closeMatch(colorWW, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_ww);
                    arforCode = "WW";
                } else if (closeMatch(colorKA, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_ka);
                    arforCode = "KA";
                } else if (closeMatch(colorAL, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_al);
                    arforCode = "AL";
                } else if (closeMatch(colorPL, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_pl);
                    arforCode = "PL";
                } else if (closeMatch(colorFD, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_fd);
                    arforCode = "FD";
                } else if (closeMatch(colorCY, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_cy);
                    arforCode = "CY";
                } else if (closeMatch(colorGE, touchColor, tolerance)) {
                    imageView2 = (ImageView) findViewById(R.id.image_ge);
                    arforCode = "GE";
                }

                if (imageView2 != null) {
                    if (imageView2.getVisibility() == View.INVISIBLE) {
                        imageView2.setVisibility(View.VISIBLE);
                        if (metflightCode == null)
                            metflightCode = arforCode;
                        else
                            metflightCode = metflightCode + ' ' + arforCode;
                    } else {
                        imageView2.setVisibility(View.INVISIBLE);
                        String[] extract = metflightCode.split(arforCode);
                        metflightCode = TextUtils.join("", extract);
                    }
                }

                Toast.makeText(this, metflightCode, Toast.LENGTH_LONG).show();

                handledHere = true;
                break;
            default:
                handledHere = false;
        } // end switch

        return handledHere;
    }

    public int getHotspotColor(int hotspotId, int x, int y) {
        ImageView img = (ImageView) findViewById(hotspotId);
        img.setDrawingCacheEnabled(true);
        Bitmap hotspots = Bitmap.createBitmap(img.getDrawingCache());
        img.setDrawingCacheEnabled(false);
        return hotspots.getPixel(x, y);
    }

    /**
     * Return true if the two colors are a pretty good match.
     * To be a good match, all three color values (RGB) must be within the tolerance value given.
     *
     * @param color1    int
     * @param color2    int
     * @param tolerance int - the max difference that is allowed for any of the RGB components
     * @return boolean
     */

    public boolean closeMatch(int color1, int color2, int tolerance) {
        if ((int) Math.abs(Color.red(color1) - Color.red(color2)) > tolerance) return false;
        if ((int) Math.abs(Color.green(color1) - Color.green(color2)) > tolerance) return false;
        if ((int) Math.abs(Color.blue(color1) - Color.blue(color2)) > tolerance) return false;
        return true;
    }


}

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_frame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
     >
    <ImageView
        android:id="@+id/image_areas"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_clickable"
        />

    <ImageView
        android:id="@+id/image"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:src="@drawable/arfor_outline"
        />

    <ImageView
        android:id="@+id/image_fn"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_fn"
        />

    <ImageView
        android:id="@+id/image_ta"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_ta"
        />

    <ImageView
        android:id="@+id/image_ed"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_ed"
        />

    <ImageView
        android:id="@+id/image_tk"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_tk"
        />

    <ImageView
        android:id="@+id/image_cp"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_cp"
        />

    <ImageView
        android:id="@+id/image_mh"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_mh"
        />

    <ImageView
        android:id="@+id/image_sa"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_sa"
        />

    <ImageView
        android:id="@+id/image_st"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_st"
        />

    <ImageView
        android:id="@+id/image_dv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_dv"
        />

    <ImageView
        android:id="@+id/image_tn"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_tn"
        />

    <ImageView
        android:id="@+id/image_ww"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_ww"
        />

    <ImageView
        android:id="@+id/image_ka"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_ka"
        />

    <ImageView
        android:id="@+id/image_al"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_al"
        />

    <ImageView
        android:id="@+id/image_pl"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_pl"
        />

    <ImageView
        android:id="@+id/image_fd"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_fd"
        />

    <ImageView
        android:id="@+id/image_cy"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_cy"
        />

    <ImageView
        android:id="@+id/image_ge"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="invisible"
        android:src="@drawable/arfor_ge"
        />

    <ImageView
        android:id="@+id/image_text"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitCenter"
        android:visibility="visible"
        android:src="@drawable/arfor_text"
        />
</FrameLayout>

2 个答案:

答案 0 :(得分:1)

通过拥有多个图像很难完成这项任务。它会占用大量内存。我想建议您遵循 ImageMapping 的概念,而不是处理多个图像。您可以通过仅使用一个图像以更精确的方式实现相同的功能。

<强>参考:

我发布的详细答案here

来自github的库和示例项目:AndroidImageMap

答案 1 :(得分:1)

重要的不是图片的压缩文件大小,而是尺寸和RGB config you choose,因为您要解码为Bitmap

我建议您在发生点击时以编程方式加载“不可见”图像,而不是使用一堆带有相应ImageView的图像预加载布局。

加载图片后,您可以在BitmapFactory.decodeResource使用该图片并将BitmapFactory.Options inPrefferedConfig设置为RGB_565 (2 bytes per pixel) or ALPHA_8 (1 byte per pixel),具体取决于图片的性质,默认情况下它是ARGB_8888,每个像素占用4个字节。在我的用例中,RGB_565在半个字节的情况下为您提供了相当好的质量,所以我会继续使用它。