2016-12-08 11 views
0

AndroidでImageViewを使用して万華鏡を作成しようとしています。私は、それぞれの 'セグメント'の回転とミラーリングを正しいものにするのに苦労しています。私は画像操作が初めてで、アンドロイドのコード例をhereに変更しようとしています。Androidでの万華鏡の効果

私は次のコードを持っている:

private void drawKaleidoscope() { 

    Bitmap bm    = BitmapFactory.decodeResource(getResources(), R.drawable.cropped_landscape); 
    Bitmap imageview_bitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888); 
    Bitmap matrix_bitmap; 
    BitmapShader fillShader; 

    Path triangle_mask = new Path(); 
    RectF r    = new RectF(0, 0, bm.getWidth(), bm.getHeight()); // create new rectangle to match the dimensions of our image 
    this.radius   = (int)r.height()/2; 

    Canvas c = new Canvas(imageview_bitmap); 
    c.drawColor(Color.BLACK); 


    float start_angle = 0; 


    for (int i = 0; i < this.segments; i++) { 

     // Create pie-slice shape mask 
     triangle_mask.reset(); 
     triangle_mask.moveTo(r.centerX(), r.centerY()); 
     triangle_mask.arcTo(r, start_angle, angle); 
     triangle_mask.close(); 


     // Use odd even check to decide when to mirror the image or not 
     if (i % 2 == 0) { 

      Matrix mat = new Matrix(); 
      mat.preTranslate(-radius, -radius); 
      mat.postRotate(i * angle); 
      mat.postTranslate(radius, radius); 

      matrix_bitmap = Bitmap.createBitmap(bm, 0, 0, (int)r.width(), (int)r.height(), mat, true); 
     } 
     else { 

      Matrix mat = new Matrix(); 

      // mirror on x axis 
      mat.postScale(-1, 1); 

      mat.postTranslate(-radius, radius); 
      mat.postRotate((float)-Math.PI); 
      mat.postRotate(i * angle); 
      mat.postTranslate(radius, -radius); 


      matrix_bitmap = Bitmap.createBitmap(bm, 0, 0, (int)r.width(), (int)r.height(), mat, true); 
     } 

     fillShader = new BitmapShader(matrix_bitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); 


     // Fill the triangle masked area with our image now 
     Paint fill = new Paint(); 
     fill.setColor(0xFFFFFFFF); 
     fill.setStyle(Paint.Style.FILL); 
     fill.setShader(fillShader); 

     c.drawPath(triangle_mask, fill); 
     start_angle += angle; 
    } 


    kal.setImageBitmap(imageview_bitmap); 
} 

上記の関数の出力はそうのようになります。誰もが適切に画像回転を行う方法にいくつかの洞察を提供することができれば

enter image description here

を/ミラーリングは非常に高く評価されるでしょう。

答えて

1

オーケー、私はこれについて別の道を進んでしまいました。ソースイメージを回転させる代わりに、イメージマスクをキャンバス上の同じ場所に描画し、キャンバス自体を回転させるだけです。私に12枚のイメージスライスがあるとしましょう。私は6つの交互の線分を描き、canvas.scale(-1、1)でキャンバスを反転し、余白がある場所に別の6つの線分を描画します。

private Bitmap generateKaleidoscopeBitmap(float start_angle) { 

    Canvas canvas = new Canvas(imageview_bitmap); 
    canvas.drawColor(Color.BLACK); 
    BitmapShader fillShader; 

    Path triangle_mask = new Path(); 
    RectF r    = new RectF(0, 0, imageview_bitmap.getWidth(), imageview_bitmap.getHeight()); // create new rectangle to match the dimensions of our image 

    int centerX = imageview_bitmap.getWidth()/2; 
    int centerY = imageview_bitmap.getHeight()/2; 

    // how much to rotate the canvas by after the image is flipped 
    float offset = calculateCanvasSymmetryOffset(start_angle); 


    // Create a pie-slice shaped clipping mask 
    triangle_mask.moveTo(r.centerX(), r.centerY()); 
    triangle_mask.arcTo(r, start_angle, angle); 
    triangle_mask.close(); 


    // Fill the triangle masked area with our shader now 
    Paint fill = new Paint(); 
    fill.setColor(0xFFFFFFFF); 
    fill.setStyle(Paint.Style.FILL); 
    fillShader = new BitmapShader(source_image, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); 
    fill.setShader(fillShader); 


    // Rotate the canvas and draw the clipping mask to the canvas 
    for (int i = 0; i < this.segments/2; i++) { 

     canvas.drawPath(triangle_mask, fill); 
     canvas.rotate(angle * 2, centerX, centerY); 
    } 


    // mirror the canvas and rotate it once to counter the symmetrical offset 
    canvas.scale(-1, 1, centerX, centerY); 
    canvas.rotate(offset, centerX, centerY); 


    // Rotate the now mirrored canvas and draw the clipping mask to it 
    // This is a cheap and easy way of creating mirrored segments 
    for (int i = 0; i < this.segments/2; i++) { 

     canvas.drawPath(triangle_mask, fill); 
     canvas.rotate(angle * 2, centerX, centerY); 
    } 

    return imageview_bitmap; 
} 
:ここに私がなってしまったコードです
関連する問題