Interesting/ANDROID | Posted by hyena0 2010. 1. 21. 21:14

[ANDROID] color mask 예제



 [ANDROID] color mask 예제

  과거에 작성했던 컬러마스크 예제를 첨부합니다.

  지속적으로 SDK 가 업데이트 되는 바람에 커스터마이징을

  해야할 겁니다.

  현재 1.6 SDK 환경에서는 동작하지 않는 군요.

  G1 폰이 업데이트가 되질 않아서 SDK 업그레이드도 멈췄지요.

  bmptest 라는 프로젝트로 작성된 코드는 아래와 같습니다.

package com.google.android.bmptest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.view.*;

public class bmptest extends Activity {
    /** Called when the activity is first created. */

 public int[]    mColors;
    @Override
    public void onCreate(Bundle icicle) {
     
        super.onCreate(icicle);
        LinearLayout linLayout = new LinearLayout(this);
        
           Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
               R.drawable.fedor);  //drawable 폴더에 fedor.bmp라는 파일이 있어야 합니다.
                                           // 원하는 파일을 넣고 파일명을 바꾸면 되겠죠.
        int width = bitmapOrg.getWidth();
        int height = bitmapOrg.getHeight();
        int newWidth = 300;
        int newHeight = 300; 
        //RGB 호출
        int[] colors = new int[width*height];
        int[][] rgbCol = new int[3][width*height];
        for(int i=0;i<2;i++){
         mColors = mask2Colors(bitmapOrg,i);
         rgbCol[i] = mColors;
        }
        for(int j=0;j<(width*height);j++){
         colors[j] = rgbCol[0][j]|rgbCol[1][j]|rgbCol[2][j]; 
        }
       
               
        // calculate the scale - in this case = 0.4f
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
       
        // createa matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight); 
        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(colors, 0, width,width,height,//STRIDE, WIDTH, HEIGHT,
                Bitmap.Config.RGB_565);
        Bitmap resizedBitmap1 =
         Bitmap.createBitmap(resizedBitmap, 0, 0,
                          width, height, matrix, true);
   
        // make a Drawable from Bitmap to allow to set the BitMap
        // to the ImageView, ImageButton or what ever

        BitmapDrawable bmd = new BitmapDrawable(resizedBitmap1);
       
        ImageView imageView = new ImageView(this);
       
        // set the Drawable on the ImageView
        imageView.setImageDrawable(bmd);
     
        // center the Image
        imageView.setScaleType(ImageView.ScaleType.CENTER);
            
        // add ImageView to the Layout
        linLayout.addView(imageView,
          new LinearLayout.LayoutParams(
                      LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT
                )
        );
       
        // set LinearLayout as ContentView
        setContentView(linLayout);
    }
   

  private int[] mask2Colors(Bitmap bitmapO, int sltColor) {
     int W,H,ST;
     int orgColor=0;
     int greenColor=0;
     //get Height and Width
     H=bitmapO.getHeight();
     W=bitmapO.getWidth();
     ST = W;
          
     int[] colors = new int[ST * H];
     int avrColor=0;
      //make mask
      int[] masks = {1,1,1,1,1,1,1,1,1};
      //Mask height, width
     int Mh = 3; int Mw =3;
      //blur
     int var=0;
            
     //get bitmap color
      for (int y = 0; y < H; y++) {
             for (int x = 0; x < W; x++) {
              if(sltColor == 0){
               orgColor = Color.red(bitmapO.getPixel(x, y));
              }
              if(sltColor == 1){
               orgColor = Color.green(bitmapO.getPixel(x, y));
              }
              if(sltColor == 2){
               orgColor = Color.blue(bitmapO.getPixel(x, y));
              }
              colors[y * ST + x] = orgColor;
             }
         }
      //calc. average value of colors
     for (int i=0;i<H*W;i++){
      avrColor += colors[i];
     }
     avrColor /= H*W;
     //mask the color
     //i는 계산될 높이 계산될 폭만큼의 반복범위임

     for (int i=0;i<(H-Mh)*(W-Mw);i++){
      
       //mask 계산
        var = colors[i]*masks[0]      + colors[i+1]*masks[1]      + colors[i+2]*masks[2]
             +colors[W+i]*masks[3]    + colors[W+i+1]*masks[4]    + colors[W+i+2]*masks[5]
             +colors[(W+1)+i]*masks[6]+ colors[(W+1)+i+1]*masks[7]+ colors[(W+1)+i+2]*masks[8];
        
        var = var/9; //1/9 효과를 나타냄
        //blur일 경우는 평균값 더하지 않기
        //var +=avrColor;
        colors[i]=var;
        var =0;//var 초기화       
     }
     
     //make argb style
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
             if(sltColor ==0){
              orgColor = colors[y * ST + x];
              orgColor = orgColor<<16;//red shift
              orgColor = 0x00FF0000 & orgColor;
             }
             if(sltColor ==1){
              orgColor = colors[y * ST + x];
              orgColor = orgColor<<8;//green shift
              orgColor = 0x0000FF00 & orgColor;
             }
             if(sltColor == 2){
              orgColor = colors[y * ST + x];
             }
             colors[y * ST + x] = orgColor;
            }
        }
      return colors;
    }
   }

  이상과 같습니다.

  주석을 보고 이해 안가는 부분이 있으시면 답글주세요.

 

 

 

댓글을 달아 주세요

  1.  댓글주소  수정/삭제  댓글쓰기 2010.01.22 14:13

    비밀댓글입니다

    •  댓글주소  수정/삭제 hyena0 2010.01.22 22:33 신고

      색이 한쪽으로 치우치는 건 원본색 때문으로 일거라고 생각했는데요.. 현재 컬러를 불러서 합치는 부분을 아무런 마스크 동작을 하지 않았을 경우에 정상이므로 문제는 없다고 보입니다. 그리고 처리속도 문제는 아무래도 임베디드 장비이다 보니 버퍼를 여러번 잡는 것은 메모리를 많이 잡아먹게 되지요. 전체 코드를 보면, 이미지 호출할때도 버퍼쓰고, 마스크 처리할때도 for 문에서 벌써 3번이나 쓰고 다시 컬러 합친다고 또 버퍼를 사용하게 됩니다. 이 횟수를 줄이는 것이 아무래도 속도향상을 시킬 수 있는 방법이겠지요. 호출한 버퍼값으로 바로 연산을 해버리는 것이 가장 효과적일 겁니다. 한번 아이디어를 내서 시도해 보시길 바랍니다. 저는 요즘 하는 것이 있어서 이 코드를 수정할 짬이 안나는 군요...^^

  2.  댓글주소  수정/삭제  댓글쓰기 2010.08.30 05:19

    비밀댓글입니다

    •  댓글주소  수정/삭제 hyena0 2010.09.03 22:15 신고

      영상이진화는 특정 레벨값 이상이면 255, 아니면 0 이런식으로 변환하는 것인데요. 굳이 마스크를 사용할 필요는 없습니다. 마스크를 쓰더라도 마스크가 지나간 만큼을 제외하고 계산해야 할테니, 전체 픽셀을 계산하는 거나 차이가 없어야 효율적인 프로그래밍이 되겠지요. 마스크는 컨볼루션이나 미분 등의 수학적 계산을 필요로 할때 사용하는 것이 효과적입니다.


  Snow leopard 에서 ddms 동작않는 문제

  MAC OS에서 발생하는 문제로
  스노우 레오파드로 업그레이드 하고 나면, 혹은
  스노우 레오파드 상태였다고 하면
  안드로이드의 ddms를 실행 시켰을때 아래와 같은 메시지가
  나타나고 동작이 되지 않을 겁니다.


13:53 E / ddms : shutting down due to uncaught exception 
13:53 E / ddms : java.lang.UnsatisfiedLinkError : / android-sdk-mac_x86-1.5_r3/tools/lib/libswt-pi-carbon-3236.jnilib : no suitable image found. Did find : / android - sdk - mac_x86-1.5_r3/tools/lib/libswt-pi-carbon-3236.jnilib : no matching architecture in universal wrapper 
at java.lang.ClassLoader $ NativeLibrary.load (Native Method) 
at java.lang.ClassLoader.loadLibrary0 (ClassLoader.java : 1878) 
at java.lang.ClassLoader.loadLibrary (ClassLoader.java : 1771) 
at java.lang.Runtime.loadLibrary0 (Runtime.java : 823) 
at java.lang.System.loadLibrary (System.java : 1045) 
at org.eclipse.swt.internal.Library.loadLibrary (Library.java : 123) 
at org.eclipse.swt.internal.carbon.OS. <clinit> (OS.java : 20) 
at org.eclipse.swt.widgets.Display.createDisplay (Display.java : 943) 
at org.eclipse.swt.widgets.Display.create (Display.java : 923) 
at org.eclipse.swt.graphics.Device. <init> (Device.java : 118) 
at org.eclipse.swt.widgets.Display. <init> (Display.java : 754) 
at org.eclipse.swt.widgets.Display. <init> (Display.java : 745) 
at com.android.ddms.UIThread.runUI (UIThread.java : 330) 
at com.android.ddms.Main.main (Main.java : 97)

  이 문제를 해결하기 위해서는

  ddms 파일을 수정해야 하는데 파일을 열면 아래와 같은 부분을 찾고

  # Mac OS X needs an additional arg, or you get an "illegal thread"complaint. 
if [`uname`= "Darwin"]; then 
os_opts = "- XstartOnFirstThread" 

다시 아래와 같이 수정(적색)해 주면 정상동작 합니다.

# Mac OS X needs an additional arg, or you get an "illegal thread"complaint. 
if [`uname`= "Darwin"]; then 
os_opts = "- XstartOnFirstThread - d32" 

스노우 레오파드가 64비트 지원이 기본이라서 이런 문제가 발생한다는 군요.



댓글을 달아 주세요

Interesting/ANDROID | Posted by hyena0 2009. 9. 10. 01:23

[Android] Publish 후에 MAP blank 문제


Publish 후에 MAP blank 문제

안드로이드의 어플을 맵 API 를 이용할 경우

마켓에 등록하기 전에 확인해야 할 것이 있습니다.

보통 MAP API의 인증 키를 받기 위해

http://code.google.com/intl/ko-KR/android/maps-api-signup.html

이곳에서 다음의 명령을 사용해서 MD5 값을 승인받는데요.


$ keytool -list -keystore ~/.android/debug.keystore
...
Certificate fingerprint (MD5): 94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98


마켓에 publish 하려면 어플 자체를 키로 암호화 해야 하는 것처럼

지도의 MAP API 도 암호화 해야 합니다.

그렇게 하지 않으면 마켓에서 다운로드 받았을 때 공백으로 보이더군요.

keytool을 이용하여 암호화하는 방법은 다음과 같습니다.

C:>D:\Programme\dev\Java\jdk1.6.0_07\bin\keytool -list -alias androiddebugkey -keystore C:\Users\plusminus\AppData\Local\Android\debug.keystore -storepass android -keypass android 
androiddebugkey, 13.10.2008, PrivateKeyEntry, 
Zertifikatsfingerabdruck (MD5): E1:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:BC

해당 내용은 anddev.org 에서 참조 했습니다.

댓글을 달아 주세요