在 Android 中如何识别图像的哪个区域(不仅仅是坐标)被触摸?

发布于 2024-10-21 04:12:32 字数 647 浏览 1 评论 0 原文

我目前正在为我的最后一年项目开发一个 Android 应用程序,该应用程序应该可以帮助自闭症患者通过触摸人体图片来指示何时感到疼痛。

我遇到的问题是我不知道如何识别他们触摸的图像部分。图像是位图,作为 ImageView 中的 BitmapDrawable 保存。第一次触摸时,它会通过动画和 setFilledAfter(true) 进行放大,当触摸某个区域时,应用程序应该识别身体的主要部分(例如头部、左手...)。

要识别的区域不是方形的,因此检查坐标并不是真正的选择。我的想法是让每个部分都被识别为在原始图片之上绘制的不同视图,但我也开放其他解决方案。

为了让事情变得更有趣,应用程序应该在不同的设备和分辨率上运行,包括手机和平板电脑。

预先非常感谢您的帮助。这确实是需要和赞赏的。

编辑

最后我将尝试以下内容。我将拥有该图像的两份副本,一份用于显示目的,另一份是内部副本,其中我想要识别的区域涂有不同的颜色。因此,计划是推断我从 Touch 事件获得的坐标,以找出它对应于原始像素的像素,使用 Bitmap.getPixel() 来确定它是什么颜色,然后有一个 case 语句返回每个部分的字符串。

我现在正在编码,如果有人感兴趣请留言,我将发布一切是如何进行的,我什至有人要求提供适当的代码:D

感谢 Shade 给了我一些其他选择来考虑。

I am currently developing an Android application for my final year project which should help autistic people indicate when something hurts and do so by touching a picture of the human body.

The problem I've encountered is I don't know how to identify the part of the image they touch. The image is a bitmap, held as a BitmapDrawable in an ImageView. First time is touched, it zooms in via an animation and setFilledAfter(true), and from there when an area is touched the app is supposed to recognize main parts of the body (e.g. head, left hand...).

The areas to be recognized aren't square so checking for coordinates is not really an option. I was thinking along the lines of having each part to be recognised as a different view drawn on top of the original picture, but I'm open too other solutions.

To make things a little bit more interesting the app should work on different devices and resolutions, in both mobiles and tablets.

Thank you so very much in advance for your help. It's really needed and appreciated.

EDIT

In the end what I will be trying is the following. I am going to have two copies of the image, one for display purposes, another internal, with the areas I want recognized painted in different colors. So the plan is to extrapolate the coordinates I obtain from the Touch event to find out to what pixel it corresponds to in regards to the original, the use Bitmap.getPixel() to determine waht color it is, then have a case statement returning the String of each part.

I am coding this right now, if anyone is interested leave a message and I will post how everything worked out, and I someone asks for it even the appropiate code :D

Thanks to Shade for giving me some other options to consider.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甲如呢乙后呢 2024-10-28 04:12:32

没有对此进行太多考虑,您的想法(使用覆盖视图检测触摸)似乎不错。

除此之外,坐标也是一个好主意 - 您只需定义图像的命名区域并检查触摸点是否在某个区域内。可能有点乏味,但与拥有 20 个视图相比,在复杂性方面可能会更好。它也肯定比在应用程序中添加 20 个额外视图更快。

但最重要的是,我认为你应该尝试一下,看看什么适合你的具体情况,因为其他一切都是猜测。

编辑:

如果您确实选择使用多边形方法,那么您将不得不处理确定点是否在多边形内部的问题(请参阅此处以获取简短说明)。

另外,关于视图,Android 中的视图被定义为“占据屏幕空间的矩形区域”。这样就消除了非矩形视图的可能性。也许您有可能在视图内定义一个非矩形的可点击区域,但我不知道这是否可能。

Without having thought too much about this, it seems that your idea - to detect touches with overlay Views - seems to be good.

Apart from that, coordinates are also a good idea - you just have to define named areas of the image and check if the point of touch is within a certain area. Could be a bit more tedious, but may be better in terms of complexity when compared to having 20 views. It will also definitely be faster than adding 20 extra views in your application.

But above all, I think that you should experiment and see what is suitable to your concrete situation, because all else is guesswork.

EDIT:

If you do choose to use the polygon method, then you will have to deal with the problem of determining whether a point is inside of a polygon (see here for a short explanation).

Also, regarding Views, a View in Android is defined as a "rectangular area that occupies space on the screen". So that eliminates the possibility of non-rectangular Views. Perhaps there is the possibility of you defining a non-rectangular clickable area inside of a View, but I don't know if that is at all possible.

殊姿 2024-10-28 04:12:32

@Alex,谢谢你的想法,它对我很有帮助。这就是我对你的解决方案的实现

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ImageView imgView = (ImageView)this.findViewById(R.id.main_screen);
    imgView.setOnTouchListener(this);
}

@Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.red);
        switch(action) {
        case MotionEvent.ACTION_DOWN:
            int x = (int)event.getX();
            int y = (int)event.getY();
            int color = bMap.getPixel(x, y) ;
            ImageView testimage = (ImageView) findViewById(R.id.main_screen);
            switch(color) {
            case Color.RED:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.red));
                break;
            case Color.BLUE:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.blue));
                break;
            }
            break;
        case MotionEvent.ACTION_UP:
            int x1 = (int)event.getX();
            int y1 = (int)event.getY();
            color = bMap.getPixel(x1, y1) ;
            testimage = (ImageView) findViewById(R.id.main_screen);
            testimage.setImageResource(R.drawable.draw);
            // TODO: Rename constant upper-case.
            final int red = 1;
            final int blue = 2;
            switch(color){
            case Color.RED:
                Intent i = new Intent(this, NewActivity.class);
                i.putExtra(NewActivity.EXT_COLOR, red);
                startActivity(i);
                break;
            case Color.BLUE:
                i = new Intent(this, NewActivity.class);
                i.putExtra(NewActivity.EXT_COLOR, blue);
                startActivity(i);
                break;
            }
            break;
        case MotionEvent.ACTION_MOVE:
            x = (int) event.getX();
            y = (int)event.getY();
            testimage = (ImageView) findViewById(R.id.main_screen);
            color = bMap.getPixel(x, y);
            switch(color){
            case Color.RED:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.red));
                break;
            case Color.BLUE:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.blue));
                break;
            default:
                testimage = (ImageView) findViewById(R.id.main_screen);
                testimage.setImageResource(R.drawable.draw);
                break;
            }
            break;
        }
        return true;
    }

@Alex, thank you for your idea, it's helped me. That's my implementation of your solution

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ImageView imgView = (ImageView)this.findViewById(R.id.main_screen);
    imgView.setOnTouchListener(this);
}

@Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.red);
        switch(action) {
        case MotionEvent.ACTION_DOWN:
            int x = (int)event.getX();
            int y = (int)event.getY();
            int color = bMap.getPixel(x, y) ;
            ImageView testimage = (ImageView) findViewById(R.id.main_screen);
            switch(color) {
            case Color.RED:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.red));
                break;
            case Color.BLUE:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.blue));
                break;
            }
            break;
        case MotionEvent.ACTION_UP:
            int x1 = (int)event.getX();
            int y1 = (int)event.getY();
            color = bMap.getPixel(x1, y1) ;
            testimage = (ImageView) findViewById(R.id.main_screen);
            testimage.setImageResource(R.drawable.draw);
            // TODO: Rename constant upper-case.
            final int red = 1;
            final int blue = 2;
            switch(color){
            case Color.RED:
                Intent i = new Intent(this, NewActivity.class);
                i.putExtra(NewActivity.EXT_COLOR, red);
                startActivity(i);
                break;
            case Color.BLUE:
                i = new Intent(this, NewActivity.class);
                i.putExtra(NewActivity.EXT_COLOR, blue);
                startActivity(i);
                break;
            }
            break;
        case MotionEvent.ACTION_MOVE:
            x = (int) event.getX();
            y = (int)event.getY();
            testimage = (ImageView) findViewById(R.id.main_screen);
            color = bMap.getPixel(x, y);
            switch(color){
            case Color.RED:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.red));
                break;
            case Color.BLUE:
                testimage.setImageDrawable(getResources().getDrawable(R.layout.blue));
                break;
            default:
                testimage = (ImageView) findViewById(R.id.main_screen);
                testimage.setImageResource(R.drawable.draw);
                break;
            }
            break;
        }
        return true;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文