Получить местоположение пикселя при нажатии в Kivy

Я использую Kivy для разработки приложения для рисования n-стороннего многоугольника поверх живого видеопотока, чтобы разграничить области интереса. У меня проблема в том, что Kivy предоставляет координаты всему окну, а не только изображению. Я хотел бы, чтобы щелкнуло местоположение пикселя (в шнурах x и y). Я просмотрел метод to_local(), но он не имел особого смысла и не дал желаемых результатов. Любая помощь будет оценена по достоинству, ниже MRE.

from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import Color, Ellipse, Line
from random import random

class ImageView(Image):

    def on_touch_down(self, touch):
        ##
        # This provides touch cords for the entire app and not just the location of the pixel clicked#
        print("Touch Cords", touch.x, touch.y)
        ##
        color = (random(), 1, 1)
        with self.canvas:
            Color(*color, mode='hsv')
            d = 30.
            Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
            touch.ud['line'] = Line(points=(touch.x, touch.y))

    def on_touch_move(self, touch):
        touch.ud['line'].points += [touch.x, touch.y]


class DMSApp(App):
    def build(self):     
        imagewidget = ImageView(source = "/home/red/Downloads/600.png")
        imagewidget.size_hint = (1, .5)
        imagewidget.pos_hint = {"top": 1}
        layout = BoxLayout(size_hint=(1, 1))
        layout.add_widget(imagewidget)
        return layout

if __name__ == '__main__':
    DMSApp().run()
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете рассчитать координаты касания относительно левого нижнего угла фактического изображения, которое появляется в графическом интерфейсе. Затем эти координаты можно масштабировать до фактического размера исходного изображения, чтобы получить разумную оценку фактических координат пикселей в источнике. Вот модифицированная версия вашего метода in_touch_down(), который делает это (проведено только минимальное тестирование):

def on_touch_down(self, touch):
    if not self.collide_point(*touch.pos):
        return super(ImageView, self).on_touch_down(touch)

    lr_space = (self.width - self.norm_image_size[0]) / 2  # empty space in Image widget left and right of actual image
    tb_space = (self.height - self.norm_image_size[1]) / 2  # empty space in Image widget above and below actual image
    print('lr_space =', lr_space, ', tb_space =', tb_space)
    print("Touch Cords", touch.x, touch.y)
    print('Size of image within ImageView widget:', self.norm_image_size)
    print('ImageView widget:, pos:', self.pos, ', size:', self.size)
    print('image extents in x:', self.x + lr_space, self.right - lr_space)
    print('image extents in y:', self.y + tb_space, self.top - tb_space)
    pixel_x = touch.x - lr_space - self.x  # x coordinate of touch measured from lower left of actual image
    pixel_y = touch.y - tb_space - self.y  # y coordinate of touch measured from lower left of actual image
    if pixel_x < 0 or pixel_y < 0:
        print('clicked outside of image\n')
        return True
    elif pixel_x > self.norm_image_size[0] or \
            pixel_y > self.norm_image_size[1]:
        print('clicked outside of image\n')
        return True
    else:
        print('clicked inside image, coords:', pixel_x, pixel_y)

        # scale coordinates to actual pixels of the Image source
        print('actual pixel coords:',
              pixel_x * self.texture_size[0] / self.norm_image_size[0],
              pixel_y * self.texture_size[1] / self.norm_image_size[1], '\n')

    color = (random(), 1, 1)
    with self.canvas:
        Color(*color, mode='hsv')
        d = 30.
        Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
        touch.ud['line'] = Line(points=(touch.x, touch.y))
    return True

Другие вопросы по теме