Используя градиент вдоль пути - PullRequest
3 голосов
/ 24 июня 2011

Я пытаюсь создать эффект свечения с помощью класса Android Path. Тем не менее, градиент не деформируется, чтобы соответствовать траектории. Вместо этого он просто отображается «над» и обрезается по траектории пути. Используя квадратный путь, изображение ниже показывает, что я имею в виду:

Path-gradient fail

Вместо этого это должно выглядеть примерно так:

enter image description here

Другими словами, градиент следует по траектории и, в частности, охватывает углы в соответствии с радиусом, установленным в CornerPathEffect.

Вот соответствующая часть кода:

paint = new Paint();
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(20);
paint.setAntiAlias(true);
LinearGradient gradient = new LinearGradient(30, 0, 50, 0,
    new int[] {0x00000000, 0xFF0000FF, 0x00000000}, null, Shader.TileMode.MIRROR);
paint.setShader(gradient);
PathEffect cornerEffect = new CornerPathEffect(10);
paint.setPathEffect(cornerEffect);
canvas.drawPath(boxPath, paint);

Есть идеи?


Другой альтернативой является получение эффекта «мягкой кромки» при определении ширины штриха. Я экспериментировал с BlurMaskFilters, но они дают равномерное размытие, а не переход от непрозрачного к прозрачному. Кто-нибудь знает, возможно ли это?

Ответы [ 4 ]

4 голосов
/ 23 августа 2013

Как насчет рисования с помощью мягкой растровой кисти?Сделайте мягкую круглую кисть с непрозрачностью, уменьшающейся радиально наружу, используя программное обеспечение для редактирования изображений, такое как Photoshop.Сохраните как пригодное для рисования, загрузите в растровое изображение и нарисуйте равномерно на вашем пути.Сделайте растровое изображение кистью белого цвета.Таким образом, вы можете просто умножить данный цвет (здесь синий) на ваше растровое изображение, используя PorterDuffColorFilter.

brush1=BitmapFactory.decodeResource(getResources(), R.drawable.brush_custom_one);
//This contains radially decreasing opacity brush
porter_paint.setColorFilter(new PorterDuffColorFilter(paint.getColor(), Mode.MULTIPLY));
for (int i=1;i<matrix.size();i++) {
//matrix contains evenly spaced points along path 
Point point = matrix.get(matrix.get(i));
canvas.drawBitmap(brush1, point.x,point.y, porter_paint);}

Используемая кисть (она есть): Brush used Окончательный результат: Final result

3 голосов
/ 19 июля 2011

Оказывается, был тупо очевидный способ сделать это. Просто повторно используйте один и тот же путь и настройте ширину и альфа обводки на каждом проходе чертежа. Пример кода:

float numberOfPasses = 20;
float maxWidth = 15;
for (float i = 0; i <= numberOfPasses; i++){
    int alpha = (int) (i / numberOfPasses * 255f);
    float width = maxWidth * (1 - i / numberOfPasses);

    paint.setARGB(alpha, 0, 0, 255);
    paint.setStrokeWidth(width);
    canvas.drawPath(path, paint);
}

См. Ниже пример результата. Левый путь был нарисован с использованием этого метода, правый путь, для сравнения, нарисован одним штрихом с maxWidth и 255 alpha.

Example of drawing result

Это в основном работает. Есть две проблемы:

  • Градиент не такой плавный, как мог бы быть. Это связано с тем, что каждый проход, проходящий поверх предыдущего, приводит к слишком быстрому наращиванию альфы, достигающему 255 перед последними ударами Помогите немного поэкспериментировать со строкой int alpha = (int) (i / numberOfPasses * 125f); (обратите внимание на изменение 125f вместо 255f).

  • Путь выглядит так, будто он был «разрезан» по внутренностям углов. Вероятно, какой-то результат применения CornerPathEffect.

2 голосов
/ 07 июля 2011

То, что вы хотите сделать, если я правильно понимаю, это сделать градиент эффективно образующим «кисть» для мазка.

Это точно , чего я тоже недавно пытался достичь, но, насколько я могу судить, API не предоставляет никаких простых средств для этого.Недавно я создал класс конвертера SVG в Android Canvas, поэтому в последнее время я тоже много работаю в Inkscape.Поэтому, когда я смотрел на это, я задавался вопросом, возможно ли вообще сделать это в Inkscape.Однако даже в Inkscape это очень нетривиальная вещь.После некоторых поисков я в конце концов наткнулся на это изображение градиента, применяемого по ходу пути, вместе со ссылкой на скачивание учебника ниже:

http://www.flickr.com/photos/35772571@N03/3312087295/

Кем я был личноПопытка сделать в то время должна была создать несколько полукругов, где путь представляет собой неоновое свечение, а не плоский цвет.Говоря об API Android и стандарте SVG, кажется, что единственный способ сделать это - создать радиальный градиент, который идеально отцентрирован по кругу, и расположить серию цветных остановок точно в нужных местах.Довольно сложно сделать, и я, конечно, не знаю, как бы вы сделали это в форме, как квадрат.

Извините, что это не что иное, как «я не мог этого сделать», а не полезный ответ!Я буду следить за этим с интересом, так как мне не терпится узнать решение для своего рода эффекта «мягкой кисти».

0 голосов
/ 17 июля 2018

Может быть очень сложно нарисовать градиент, чем следовать по пути. Поэтому я предлагаю вам использовать уже готовую библиотеку, чем сделать ее для вас. Можно быть Sc-Gauges .

Имейте несколько полезных классов, которые вы можете использовать для своей цели.

Для первого включите библиотеку:

dependencies {
    ...
    compile 'com.github.paroca72:sc-gauges:3.0.7'
}

После создания изображения или того, что вы хотите, с холстом, где рисуйте:

<ImageView
      android:id="@+id/image"
      android:layout_width="match_parent"
      android:layout_height="match_parent" 
/>

Теперь код:

    // Dimensions
    int padding = 24;
    Rect drawArea = new Rect(padding, padding, 700 - padding, 500 - padding);

    // Get the main layout
    ImageView imageContainer = (ImageView) this.findViewById(R.id.image);
    assert imageContainer != null;

    // Create a bitmap and link a canvas
    Bitmap bitmap = Bitmap.createBitmap(
            drawArea.width() + padding * 2, drawArea.height() + padding * 2,
            Bitmap.Config.ARGB_8888
    );
    Canvas canvas = new Canvas(bitmap);
    canvas.drawColor(Color.parseColor("#f5f5f5"));

    // Create the path building a bezier curve from the left-top to the right-bottom angles of
    // the drawing area.
    Path path = new Path();
    path.moveTo(drawArea.left, drawArea.top);
    path.quadTo(drawArea.centerX(), drawArea.top, drawArea.centerX(), drawArea.centerY());
    path.quadTo(drawArea.centerX(), drawArea.bottom, drawArea.right, drawArea.bottom);

    // Feature
    ScCopier copier = new ScCopier();
    copier.setPath(path);
    copier.setColors(Color.RED, Color.GREEN, Color.BLUE);
    copier.setWidths(20);
    copier.draw(canvas);

    // Add the bitmap to the container
    imageContainer.setImageBitmap(bitmap);

И вот результат:

enter image description here

Первая часть кода предназначена только для создания растрового изображения с рисованием. Что вас интересует, так это вторая часть, где используется ScCopier. Просто дайте путь, цвет и с.

Обратите внимание, что вы внутри вида, вы можете использовать onDraw для рисования непосредственно на холсте вида.

Эта библиотека может использоваться для создания датчиков любого вида. Если вы хотите взглянуть на этот сайт, ScComponents имеет несколько бесплатных и некачественных компонентов.

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