2017-07-13 5 views
1

私は、ビットマップ上ビットマップにストロークのような効果を与える方法はありますか?

paint.setStyle(Paint.Style.STROKE) 
canvas.drawText(string, x, y, paint); 

は、テキストのために何をするかと同等の効果を達成したいと思います。

BlurMaskFilterに似ていますが、ストローク、グロー、シャドウではありません。

組み込みの方法がない場合は、おそらく誰かがこれを達成するためのアルゴリズムを提案できますか?

+0

あなたが効果を示すサンプル画像を追加してもらえますか? – Zielony

+0

@Zielony:悲しいことに、イメージには10の評判要件があります。しかし、おそらくこれはうまくいく:https://i.stack.imgur.com/EWNnE.png(右に1つはストロークされている) – hundreAd

+0

これらの10ポイントを捕まえる:)これはあなたのイメージがベクトル。ビットマップイメージを使用する予定ですか? – Zielony

答えて

0
private Bitmap multiplyAlpha(final Bitmap bitmap, Paint paint, 
     final boolean color, final float x) { 
    paint = new Paint(paint.getFlags()); 
    Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), 
      bitmap.getHeight(), color ? Config.ARGB_8888 : Config.ALPHA_8); 
    // ColorMatrixColorFilter requires ARGB. 
    Bitmap auxiliary = Bitmap.createBitmap(bitmap.getWidth(), 
      bitmap.getHeight(), Config.ARGB_8888); 
    new Canvas(auxiliary).drawBitmap(bitmap, 0, 0, paint); 
    // @formatter:off 
    paint.setColorFilter(new ColorMatrixColorFilter(new float[] { 
       1, 0, 0, 0, 0, 
       0, 1, 0, 0, 0, 
       0, 0, 1, 0, 0, 
       0, 0, 0, x, 0 
    })); 
    // @formatter:on 
    new Canvas(result).drawBitmap(auxiliary, 0, 0, paint); 
    return result; 
} 

private Bitmap opaque(final Bitmap bitmap, Paint paint, final boolean color) { 
    return multiplyAlpha(bitmap, paint, color, 255); 
} 

private RectF inset(final RectF rectF, final float dx, final float dy) { 
    RectF result = new RectF(rectF); 
    result.inset(dx, dy); 
    return result; 
} 

private RectF offset(final RectF rectF, final float dx, final float dy) { 
    RectF result = new RectF(rectF); 
    result.offset(dx, dy); 
    return result; 
} 

private Bitmap antialias(final Bitmap bitmap, Paint paint, 
     final float radius) { 
    Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), 
      bitmap.getHeight(), Config.ALPHA_8); 
    if (radius > 0) { 
     paint = new Paint(paint.getFlags()); 
     Canvas canvas = new Canvas(result); 
     Bitmap opaque = opaque(bitmap, paint, false); 
     canvas.drawBitmap(opaque, 0, 0, paint); 
     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
     paint.setMaskFilter(new BlurMaskFilter(radius, Blur.INNER)); 
     canvas.drawBitmap(opaque, 0, 0, paint); 
    } 
    return result; 
} 

private Bitmap stroke(final Bitmap bitmap, Paint paint, final float radius, 
     final RectF rectF, final float dx, final float dy) { 
    paint = new Paint(paint.getFlags()); 
    Bitmap result = Bitmap.createBitmap(
      (int) Math.ceil(rectF.width() + 2 * radius), 
      (int) Math.ceil(rectF.height() + 2 * radius), Config.ALPHA_8); 
    if (radius > 0) { 
     paint.setMaskFilter(new BlurMaskFilter(radius, Blur.NORMAL)); 
     new Canvas(result).drawBitmap(opaque(bitmap, paint, false), null, 
       offset(rectF, -dx, -dy), paint); 
    } 
    return result; 
} 

private Bitmap stroke(final Bitmap bitmap, Paint paint, final float radius, 
     final RectF rectF, final int color, final float antialias, 
     final float factor, final boolean fill, final float dx, 
     final float dy) { 
    paint = new Paint(paint.getFlags()); 
    Canvas canvas = new Canvas(); 
    paint.setColor(color); 
    Bitmap stroke = stroke(bitmap, paint, radius, rectF, dx, dy); 

    Bitmap auxiliary = Bitmap.createBitmap(stroke.getWidth(), 
      stroke.getHeight(), Config.ALPHA_8); 
    canvas.setBitmap(auxiliary); 
    // Paint [opaque] stroke. 
    canvas.drawBitmap(opaque(stroke, paint, false), 0, 0, paint); 
    // Antialias stroke with outside. 
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
    Bitmap outer = multiplyAlpha(antialias(stroke, paint, antialias), 
      paint, false, factor); 

    canvas.drawBitmap(outer, 0, 0, paint); 
    paint.setXfermode(null); 

    // If FILL, leave the inside filled with color (this is the way e.g. 
    // Photoshop strokes); otherwise, the stroke will be only on the outside 
    // of the bitmap; the more transparent the bitmap, the more noticeable 
    // the effect. 
    if (!fill) { 
     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 
     canvas.drawBitmap(opaque(bitmap, paint, false), null, 
       offset(rectF, -dx, -dy), paint); 
     paint.setXfermode(null); 
    } 

    Bitmap result = Bitmap.createBitmap(auxiliary.getWidth(), 
      auxiliary.getHeight(), bitmap.getConfig()); 
    canvas.setBitmap(result); 
    RectF output = offset(rectF, -dx, -dy); 
    canvas.drawBitmap(auxiliary, null, inset(output, -radius, -radius), 
      paint); 
    // Paint bitmap. 
    canvas.drawBitmap(bitmap, null, output, paint); 
    // Antialias stroke with bitmap. 
    Bitmap inner = multiplyAlpha(antialias(bitmap, paint, antialias), 
      paint, false, factor); 
    canvas.drawBitmap(inner, null, output, paint); 

    return result; 
} 

private void stroke(final Bitmap bitmap, Paint paint, final float radius, 
     final RectF rectF, final int color, final float antialias, 
     final float factor, final boolean fill, Canvas canvas) { 
    float dx = rectF.left - radius; 
    float dy = rectF.top - radius; 
    Bitmap stroke = stroke(bitmap, paint, radius, rectF, color, antialias, 
      factor, fill, dx, dy); 
    canvas.drawBitmap(stroke, dx, dy, paint); 
} 

  • antialias
  • factorはアンチエイリアス強度
  • fillは外側のみストロークするかどうか偽塗料を示し、または変更アンチエイリアス効果の幅al内部をと記入してください(これは方法です)。 Photoshopのストローク);より透明bitmapは、より顕著な効果
  • rectFはRectFが

用法で描画することを示す(例えば):

stroke(bmp, paint, radius, rectF, 0xffff0000, antialias, factor, fill, canvas); 
関連する問題