2014-09-30 3 views
1

Как я могу получить изображение с шестиугольником, которое показано ниже.Android Hexagon ImageView

http://imgur.com/1PEGuQu

Обратите внимание, что я попробовал решение, которое на этот вопрос: How to give hexagon shape to ImageView

И я также попытался это решение: Masking(crop) image in frame

Но я не хочу, чтобы заполнить цвет вне шестиугольника. Я хочу, чтобы он был прозрачным, чтобы можно было видеть взгляды и образы.

Кстати, я попробовал, BitmapShader, PorterDuffXFermode и т. Д., Но мне не удалось получить результат.

Заранее спасибо.

ответ

2

Я наконец решил свою проблему. Я нахожу очень полезную библиотеку, которая специально делает трюк, который я хотел. Он маскирует изображение с помощью векторного изображения типа svg.

Библиотека:

CustomShapeImageView

Результат:

Screenshot

Edit: Я также хочу поделиться с шестигранной СВГ с вами, в случае необходимости.

<svg width="205" height="237" xmlns="http://www.w3.org/2000/svg"> 
<title>hexagon</title> 
<metadata id="metadata3064">image/svg+xml</metadata> 
<g> 
<title>Layer 1</title> 
<polygon points="0,59.27092742919922 0,177.8127899169922 102.66026306152344,237.08370971679688 205.3205108642578,177.8127899169922 205.3205108642578,59.27092742919922 102.66026306152344,0 " id="svg_1" fill="#000000"/> 
</g> 
</svg> 
+0

Привет. SafaOrhan, svg необходимо сохранить в какой папке и в каком расширении? – Jack

+1

@Jack Вы можете поместить его в папку/res/raw без расширения. – SafaOrhan

0

Я прочитал это и выглядит действительным. У них даже есть видео-учебник: http://www.41post.com/4794/programming/android-rendering-a-path-with-a-bitmap-fill о том, как заполнить фигуру текстурой

+0

Я не хочу, чтобы заполнить цветом. Я хочу замаскировать его так, чтобы его можно было увидеть. – SafaOrhan

+0

Используя их, вы можете создать прозрачное изображение с текстурированной формой. – eduyayo

3

Вот мой код для этого, это поддерживает теней:

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapShader; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.PorterDuff; 
import android.graphics.Shader; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.AttributeSet; 
import android.widget.ImageView; 

public class HexagonImageView extends ImageView { 

    private Path hexagonPath; 
    private Path hexagonBorderPath; 
    private float radius; 
    private Bitmap image; 
    private int viewWidth; 
    private int viewHeight; 
    private Paint paint; 
    private BitmapShader shader; 
    private Paint paintBorder; 
    private int borderWidth = 4; 

    public HexagonImageView(Context context) { 
     super(context); 
     setup(); 
    } 

    public HexagonImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setup(); 
    } 

    public HexagonImageView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     setup(); 
    } 

    private void setup() { 
     paint = new Paint(); 
     paint.setAntiAlias(true); 

     paintBorder = new Paint(); 
     setBorderColor(Color.WHITE); 
     paintBorder.setAntiAlias(true); 
     this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); 
     paintBorder.setShadowLayer(4.0f, 1.0f, 1.0f, Color.BLACK); 

     hexagonPath = new Path(); 
     hexagonBorderPath = new Path(); 
    } 

    public void setRadius(float r) { 
     this.radius = r; 
     calculatePath(); 
    } 

    public void setBorderWidth(int borderWidth) { 
     this.borderWidth = borderWidth; 
     this.invalidate(); 
    } 

    public void setBorderColor(int borderColor) { 
     if (paintBorder != null) 
      paintBorder.setColor(borderColor); 

     this.invalidate(); 
    } 

    private void calculatePath() { 

     float triangleHeight = (float) (Math.sqrt(3) * radius/2); 
     float centerX = viewWidth/2; 
     float centerY = viewHeight/2; 

     hexagonBorderPath.moveTo(centerX, centerY + radius); 
     hexagonBorderPath.lineTo(centerX - triangleHeight, centerY + radius/2); 
     hexagonBorderPath.lineTo(centerX - triangleHeight, centerY - radius/2); 
     hexagonBorderPath.lineTo(centerX, centerY - radius); 
     hexagonBorderPath.lineTo(centerX + triangleHeight, centerY - radius/2); 
     hexagonBorderPath.lineTo(centerX + triangleHeight, centerY + radius/2); 
     hexagonBorderPath.moveTo(centerX, centerY + radius); 

     float radiusBorder = radius - borderWidth;  
     float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder/2); 

     hexagonPath.moveTo(centerX, centerY + radiusBorder); 
     hexagonPath.lineTo(centerX - triangleBorderHeight, centerY + radiusBorder/2); 
     hexagonPath.lineTo(centerX - triangleBorderHeight, centerY - radiusBorder/2); 
     hexagonPath.lineTo(centerX, centerY - radiusBorder); 
     hexagonPath.lineTo(centerX + triangleBorderHeight, centerY - radiusBorder/2); 
     hexagonPath.lineTo(centerX + triangleBorderHeight, centerY + radiusBorder/2); 
     hexagonPath.moveTo(centerX, centerY + radiusBorder); 

     invalidate(); 
    } 

    private void loadBitmap() { 
     BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable(); 

     if (bitmapDrawable != null) 
      image = bitmapDrawable.getBitmap(); 
    } 

    @SuppressLint("DrawAllocation") 
    @Override 
    public void onDraw(Canvas canvas){ 
     super.onDraw(canvas); 

     loadBitmap(); 

     // init shader 
     if (image != null) { 

      canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); 

      shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
      paint.setShader(shader); 

      canvas.drawPath(hexagonBorderPath, paintBorder); 
      canvas.drawPath(hexagonPath, paint); 
     } 

    } 

    @Override 
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     int width = measureWidth(widthMeasureSpec); 
     int height = measureHeight(heightMeasureSpec, widthMeasureSpec); 

     viewWidth = width - (borderWidth * 2); 
     viewHeight = height - (borderWidth * 2); 

     radius = height/2 - borderWidth; 

     calculatePath(); 

     setMeasuredDimension(width, height); 
    } 

    private int measureWidth(int measureSpec) { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpec); 
     int specSize = MeasureSpec.getSize(measureSpec); 

     if (specMode == MeasureSpec.EXACTLY) { 
      result = specSize; 
     } 
     else { 
      result = viewWidth; 
     } 

     return result; 
    } 

    private int measureHeight(int measureSpecHeight, int measureSpecWidth) { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpecHeight); 
     int specSize = MeasureSpec.getSize(measureSpecHeight); 

     if (specMode == MeasureSpec.EXACTLY) { 
      result = specSize; 
     } 
     else { 
      result = viewHeight; 
     } 

     return (result + 2); 
    } 


}