그림 처리: 색상 매트릭스 와 좌표 변환 매트릭스

7002 단어 사진 처리
아 이언 의 개인 블 로그 [http://www.icodelogic.com] 본문 링크 주소:  http://www.icodelogic.com/?p=559
 
UI 개발 과정 에서 우 리 는 항상 그림 을 처리 해 야 한다. 예 를 들 어 스티커, 복잡 한 것 은 위치 변환, 회전, 필터 효과 등 이 있다. 다음은 그림 처리 에 관 한 기본 지식 과 원 리 를 간단하게 소개 한다.
1. 기본 개념 은 이미지 의 처리 에 있어 가장 자주 사용 되 는 데이터 구 조 는 Bitmap 입 니 다. 이 데이터 구 조 는 한 장의 그림 의 모든 데 이 터 를 포함 합 니 다. 이런 데이터 데 이 터 는 그 내용 을 포함 합 니까?쉽게 말 하면 격자 와 색상 값 으로 구 성 된 것 이다. 이른바 격자 란 개념 적 으로 Width * Height 의 행렬 로 모든 요 소 는 그림 의 픽 셀 에 대응 된다. 즉, 격자 는 그림 의 공간 위치 정 보 를 저장 하고 있다.한편, 색상 값 은 ARGB 로 투명도, 빨간색, 녹색, 파란색 등 네 개의 채널 분량 에 대응 하고 각 채널 은 8 비트 로 정의 하기 때문에 하나의 색상 값 은 int 정형 으로 256 * 256 * 256 의 색상 값 을 나 타 낼 수 있다.
Android 에서 우 리 는 이렇게 몇 개의 상수 에 자주 사용 합 니 다: ARGB8888、ARGB_4444、RGB_565。이 몇 개의 상수 들 은 사실은 시스템 에 그림 의 색상 값 을 어떻게 처리 하 는 지 알려 주 는 것 이다. 예 를 들 어 ARGB8888 은 시스템 투명도, R, G, B 가 색상 값 에서 각각 8bit 로 표시 하 는 것 을 알려 주 는 것 이다. 이때 색상 값 은 32bit 이 고 이런 정 의 는 가장 많은 색상 값 을 나 타 낼 수 있 으 며 그림 의 질 도 가장 좋다.ARGB_4444 는 모든 채널 에서 4bit 로 표시 하 는데 이런 색상 수 치 는 16bit 로 공간 을 절약 하지만 16 * 16 * 16 가지 색상 만 표시 할 수 있다. 즉, 그림 은 색채 정 보 를 많이 잃 었 다 는 것 이다.RGB_565 유형의 색상 값 역시 16bit 이지 만 투명도 정 보 를 버 려 32 * 64 * 32 가지 색상 값 을 표시 할 수 있 습 니 다.
2. 색상 매트릭스 색상 행렬 은 5 * 4 의 행렬 로 그림 색상 값 을 처리 합 니 다.색상 매트릭스 와 색상 값 을 다음 과 같이 정의 합 니 다.
图片处理:颜色矩阵和坐标变换矩阵 다음 과 같은 행렬 연산 을 실시 합 니 다. 图片处理:颜色矩阵和坐标变换矩阵 결과 R 은 4 * 1 의 행렬 입 니 다. 이 행렬 은 바로 새로운 색상 값 입 니 다. R 에서 각 채널 의 값 은 각각 다음 과 같 습 니 다. R '= a * R + b * G + c * B + d * A + e;G’ = f*R + g*G + h*B + i*A + j;B’ = k*R + l*G + m*B + n*A + o;A’ = p*R + q*G + r*B + s*A + t;
이렇게 보면 추상 적 이 고 색채 행렬 과 결과 R 의 직접적인 관 계 를 이해 하기 어 려 울 것 이다. 우 리 는 색채 행렬 의 값 이 다음 과 같다 고 가정 한다.
图片处理:颜色矩阵和坐标变换矩阵
그러면 결 과 는 R = R 이다.G’ = G;B’ = B;A’ = A;즉, 새로운 색상 값 은 원래 의 것 과 같다!예 를 들 어 색채 행렬 의 수 치 는 다음 과 같다. 图片处理:颜色矩阵和坐标变换矩阵 결 과 는 R '= R + 100 이다.G’ = G + 100;B’ = B;A’ = A;새로운 색상 값 에 서 는 빨간색 채널 값 과 녹색 채널 값 이 각각 100 증가 하 는데 이때 그림 이 누 렇 게 됩 니 다 (R + G = Yellow 때 문 입 니 다).
위의 몇 가지 예 를 들 어 우 리 는 색채 행렬 의 모든 분량 (각 열) 의 의 미 를 쉽게 알 수 있다. 첫 번 째 줄 은 빨간색 을 결정 하고 두 번 째 줄 은 녹색 을 결정 하 며 세 번 째 줄 은 파란색 을 결정 한다. 네 번 째 줄 은 투명 도 를 결정 하고 다섯 번 째 열 은 색채 의 오프셋 이다.이로써 우 리 는 색 행렬 을 통 해 색 값 의 각 분량 을 어떻게 바 꾸 는 지 이해 할 수 있 을 것 이다.
다음은 안 드 로 이 드 에 사용 되 는 코드 입 니 다. 그림 을 노란색 으로 처리 하 는 데 사 용 됩 니 다.
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

    public static Bitmap testBitmap(Bitmap bitmap)

    {

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),

                bitmap.getHeight(), Config.RGB_565);

 

        Canvas canvas = new Canvas(output);

 

        Paint paint = new Paint();        

        ColorMatrix cm = new ColorMatrix();

        float[] array = {1,0,0,0,100,

                0,1,0,0,100,

                0,0,1,0,0,

                0,0,0,1,0};

        cm.set(array);

        paint.setColorFilter(new ColorMatrixColorFilter(cm));

 

        canvas.drawBitmap(bitmap, 0, 0, paint);

        return output;

    }

3. 좌표 변환 행렬 이 그림 에 대한 조작 은 색채 값 의 처 리 를 제외 하고 가장 자주 사용 하 는 것 은 공간 좌표 의 변환 이다. 흔히 볼 수 있 는 효 과 는 이동, 회전, 스 트 레 칭 등 이 있 는데 이것 도 하나의 행렬 을 통 해 이 루어 진 것 이다.좌표 변환 행렬 은 3 * 3 의 행렬 로 유사 한 (X, Y, 1) 좌표 값 의 행렬 곱셈 연산 을 통 해 이 좌표 값 을 새로운 좌표 값 으로 변환 할 수 있 습 니 다. 계산 과정 은 다음 과 같 습 니 다. 결 과 는 x '= a * x + b * y + cy' = d * x + e * y + f 같은 색 행렬 과 같 습 니 다. 좌표 가 행렬 을 다음 과 같이 바 꾸 면 새로운 좌표 값 X, Y 가 50 증가 합 니 다.즉, 그림 의 모든 점 이 (50, 50) 의 거 리 를 평평 하 게 옮 겼 다 는 것 이다. 즉, 그림 전체 가 (50, 50) 좌표 로 옮 겼 다 는 것 이다.图片处理:颜色矩阵和坐标变换矩阵 좌표 가 행렬 을 다음 과 같이 바 꾸 면 모든 X, Y 좌 표 는 두 배로 커진다. 즉, 그림 이 두 배로 확대 되 고 다른 확대 효과 원 리 는 유사 하 다.图片处理:颜色矩阵和坐标变换矩阵 좀 더 복잡 한 것 은 회전 효과 도 있다. 하나의 회전 변환 행렬 은 다음 과 같다. 결 과 는 x '= xcos 이다.θ – ysinθ 와 y '= xsinθ + ycosθ,이 결과 의 효 과 는 원점 에서 시계 반대 방향 으로 회전 하 는 것 이다.θ각도
다음은 Android 에 사용 되 는 예제 코드 입 니 다. 그림 을 평평 하 게 이동 시 키 는 데 사 용 됩 니 다. 즉, 재단 효과 입 니 다. 다른 효 과 는 해당 좌표 변환 행렬 을 참조 하여 수정 하면 됩 니 다.
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

    public static Bitmap test1Bitmap(Bitmap bitmap)

    {

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),

                bitmap.getHeight(), Config.RGB_565);

 

        Canvas canvas = new Canvas(output);

 

        Paint paint = new Paint();        

        Matrix cm = new Matrix();

 

        float[] array = {1,0,50,

                0,1,50,

                0,0,1};

        cm.setValues(array);

        canvas.drawBitmap(bitmap, cm, paint);

        return output;

    }

좋은 웹페이지 즐겨찾기