2011-03-08 5 views
3

반사 그림자를 만들려고하고 있는데 문제가 있습니다. 두 그림을 내가Android : 셰이더가 'onDraw (캔버스)'및 '새 캔버스 (비트 맵)'에서 다르게 동작 함

을 (new Canvas(bitmap)를 사용하여 만든) (나는 onDraw(canvas)에서 가지고있는)과 canvas2 캔버스에 같은 일을하고

@Override 
protected void onDraw(Canvas canvas) { 
    //prepare 
    canvas.drawColor(Color.GRAY); 
    Bitmap source = BitmapFactory.decodeResource(getResources(), R.drawable.icon); 

    //First Column 
    canvas.drawBitmap(source, 0, 0, new Paint()); 

    //2nd Column 
    canvas.drawBitmap(source, source.getWidth(), 0, new Paint()); 

    //Reflection 
    Matrix matrix = new Matrix(); 
    matrix.preScale(1.0f, -1.0f); 
    matrix.postTranslate(source.getWidth(), source.getHeight()*2); 
    canvas.drawBitmap(source, matrix, new Paint()); 

    Paint paint2 = new Paint(); 
    LinearGradient shader = new LinearGradient(
      source.getWidth()*3/2, 
      source.getHeight(), 
      source.getWidth()*3/2, 
      source.getHeight()*2, 
      0x7FFFFFFF, 0x00FFFFFF, TileMode.CLAMP); 
    paint2.setShader(shader); 
    paint2.setXfermode(new PorterDuffXfermode(
      android.graphics.PorterDuff.Mode.DST_IN)); 
    canvas.drawRect(
      source.getWidth(), 
      source.getHeight(), 
      source.getWidth()*2, 
      source.getHeight()*2, 
      paint2); 

    //3rd Column 
    Bitmap bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight()*2, Config.ARGB_8888); 
    Canvas canvas2 = new Canvas(bitmap); 
    canvas2.drawBitmap(source, 0, 0, new Paint()); 
    matrix = new Matrix(); 
    matrix.preScale(1.0f, -1.0f); 
    matrix.postTranslate(0, source.getHeight()*2); 
    canvas2.drawBitmap(source, matrix, new Paint()); 


    paint2 = new Paint(); 
    shader = new LinearGradient(
      source.getWidth()*1/2, 
      source.getHeight(), 
      source.getWidth()*1/2, 
      source.getHeight()*2, 
      0x7FFFFFFF, 0x00FFFFFF, TileMode.CLAMP); 
    paint2.setShader(shader); 
    paint2.setXfermode(new PorterDuffXfermode(
      android.graphics.PorterDuff.Mode.DST_IN)); 
    canvas2.drawRect(
      0, 
      source.getHeight(), 
      source.getWidth(), 
      source.getHeight()*2, 
      paint2); 

    canvas.drawBitmap(bitmap, source.getWidth()*2,0, new Paint()); 
} 

을하지만 :

내 사용자 정의보기에 아래의 코드를 찾아주세요 다른 쉐이더 효과는 다음과 같습니다 : different shader effect

쉐이더 효과가 다른 이유는 무엇입니까?

PorterDuff.MODE.DST_IN가 [사행 * 다, SA * DC]과 같이 정의된다 : 두 번째 열에서 검은 사각형을 고려

답변

3

. 대상 픽셀은 불투명 한 회색 (Da = 1)이므로 결과의 알파 채널은 선형 그래디언트의 알파 채널로 설정됩니다.

그리고 거기에 문제가 있습니다. ... 두 번째 열에서 Window 캔버스의 픽셀을 부분적으로 투명하게 설정합니다. 아래에서 무엇을 볼 수 있습니까? 창 배경은 여전히 ​​기본 검정색입니다.

세 번째 열에서는 먼저 오프 스크린 비트 맵으로 그리는 중이고 부분적으로 투명한 오프 스크린 비트 맵을 나중에 Windows 캔버스로 그립니다. 이는 오프 스크린 비트 맵에서 들어오는 픽셀이 이미 존재하지만 대상 버퍼와 블렌딩 된 픽셀을 완전히 대체하지 않기 때문에 효과적입니다 (PorterDuff 용어로 볼 때 SRC_ATOP과 같음).

+0

설명해 주셔서 감사합니다. –

+0

설명해 주셔서 감사합니다. 하지만 여전히 원본과 대상에 대해 명확하지 않습니다. 대상은 drawRect() 호출 (캔버스 위에 이미지가 그려져 있음) 전에 캔바스의 상태가 아닙니다. 오히려 그것이 창조되었을 때의 상태. 제 3 열 소스 코드를 \t \t // 3 열로 변경했습니다. \t \t 비트 맵 bitmap = Bitmap.createBitmap (source.getWidth(), 2, Config.RGB_565); \t \t bitmap.eraseColor (Color.GRAY); 두 번째 열과 동일하게됩니다. 캔버스가 onDraw (캔버스)에서 오프 스크린 비트 맵 캔버스로 동작하도록 변경할 수없는 것 같습니다. –

+0

Config.RGB_565를 사용하는 경우 오프 스크린 비트 맵의 ​​알파 채널을 버리므로 창 캔버스에 그릴 때 블렌딩 할 수 없습니다. 단순히 대상 픽셀을 대체합니다. –

관련 문제