Как реализовать маску изображения? - PullRequest
0 голосов
/ 14 декабря 2011

Ситуация:

Я работаю над небольшим приложением, которое должно позволить пользователю запускать что-то в зависимости от того, какую часть экрана они щелкнули.Представьте себе изображение плюшевого мишки, и если вы щелкнете по носу, на нем появится надпись «нос».То, что я сделал, это поместил в макет xml LinearLayout.Поскольку я должен покрывать разные размеры экрана, я не установил фон в файле макета xml.

Фрагмент xml:

<FrameLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/viewMain"            
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:visibility="visible" >    
  <LinearLayout
        android:id="@+id/viewThouShaltRespondToClicks"
            android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:orientation="vertical"
        android:longClickable="true"
        android:visibility="visible" />

  <!-- mask -->
  <LinearLayout
    android:id="@+id/viewInvisibleMask"
    android:visibility="invisible"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
  </LinearLayout>
</FrameLayout>

А затем в событии активности onCreate я проверяю отображениеразрешение и через setBackgroundResource () установить соответствующий фон.Я подготовил фоновые изображения для каждого разрешения.

final Point QVGA = new Point(240,320);  // portrait
// Obtain the screen resolution if the device
Display defaultDisplay = ((WindowManager)this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point displayResolution = new Point(defaultDisplay.getWidth(), defaultDisplay.getHeight());
if (displayResolution.equals(QVGA))
        {
           viewThouShaltRespondToClicks.setBackgroundResource(R.drawable.image_to_be_clicked_upon_240x320);
viewInvisibleMask.setBackgroundResource(R.drawable.mask_240x320);

       }
else if ... // check for another resolution

Даже если изображение в ресурсах имеет неправильный размер, оно растягивается / уменьшается до размера экрана.Это было бы нормально, если отношение ширины к высоте фонового изображения аналогично отношению отображения, а результирующее изображение не сильно перекошено.Но есть проблема, объясненная ниже.

Чтобы определить, какая область была нажата, сама область может иметь неправильную форму. Я выбрал следующий подход.Я создаю изображение - маску (bmp) с такими же размерами, что и у фонового изображения, только с тем, чтобы оно имело белый фон, а интерактивные области были разных цветов.Цвет идентифицирует область.Все, что мне нужно, это получить координату события щелчка (здесь нет проблем), перейти к изображению маски и прочитать цвет пикселя по этим координатам.Проблема в том, что изображение маски имеет неправильный размер.На моем устройстве оно установлено на 1200x700, но я предполагаю, что оно принимает произвольный размер на других устройствах.

Первый вопрос: есть ли способ как-то убедить невидимый макет загрузить фоновое изображение, а затем растянуть / сжатьон отображает размер, как это происходит для видимого макета сам по себе?

Другой подход заключается в загрузке изображения маски (bmp, png) в некоторую структуру памяти и изменении ее размера для отображения размера.Я пробовал что-то вроде:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;   // do not scale
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmapMask = BitmapFactory.decodeResource(this.getResources(), R.drawable.mask, options);
// on this place stretch shrink should follow but I have no idea how

Но я не знаю, как масштабировать растровое изображение до нужного размера.

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 14 декабря 2011

Просто простое предложение. Вы могли бы иметь эталонное изображение в виде изображения за реальным изображением. Таким образом, оба изображения загружаются одинаковым образом, помещаются в ImageViews, а затем вставляются в относительный макет. Таким образом, они должны быть одинакового размера, и виден только один из них.

Возможно, это не очень приятный способ сделать это, и я не уверен, сработает ли это, но вы можете попробовать это.

0 голосов
/ 14 декабря 2011

Первый вопрос: да, вы можете иметь отдельный вид в макете, содержащий изображение маски, и установить его как невидимый с помощью android:visibility=invisible.

Второй вопрос: вы можете прочитать значение пикселя из растрового изображения с помощью Bitmap.getPixel(). Документы здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...