EMPOS-II 라는 기기가 있습니다

(주 : 한빛전자의 EMPOS II 설명 http://www.hanback.co.kr/htm/sub2_2.htm)

임베이드 시스템 (CPU가 인텔 호환 계열 PC가 아닌, PDA나 휴대폰, 게임기에 들어가는 ARM 계열)의 프로그래밍을
교육 목적으로 만들어 졌다는 기계입니다 ... (;;;)

운영체제 시간때 프로그래밍으로 이 기계 가지고 게임을 만들라는군요.. (게임 공학과 답..)
뭐... CPU 400 Mhz 급... 렘 64MB .. 3D짓을 하면 일이 복잡하니.. 간단한 게임 만들자 해서...



일단 익숙한 윈도우 API 환경.. (임베이드 장비는 웬만하면 리눅스를 사용합니다.)으로 프로토 타입을 뽑았습니다.
30분 가량 대충 뚜둘겨 만든겁니다.. (컬러키니 뭐니 그런거 프로토 타입에 필요 없으니.. 애초에 이게 목적이 아니니)
(해당 소스.. API)

뭐 흔한 플래쉬 게임인 위에서 떨어지는 케릭터를 맞춰서 점수를 올리는
흔한... 낙하병 맞추기 게임 입니다.. (케릭터가.. 전혀 낙하산이 없지만;;;)

음.. 그 다음... 리눅스 기반의 프로그래밍은 vim을 사용하기에.. (전.. 이맥스 인가.. 그걸 씁니다. orz)
그래픽을 삽입하는법을 어떻게 할까 하다가...
예전 닌텐도 DS 만졌을때 윈도우 BMP 파일을 그쪽 NDS에 업로드 해서 띄울때 C언어, 즉 배열에다가 각 픽셀값을 다 때려박아 버리는 무식한 방법.. 이 떠올라

이전에 만든 프로그램을 좀 개조해서 EMPOS-II 에서 제대로 나오게 개조 했습니다.

음.. 이렇게 보니 무슨 암호문 같군요 ㅋㅋ 참고로 0xF81F 는.. 위의 RGB(255,0,255) 투명색을..
16진수상... 0xff00ff00를 각각 RGB 5,6,5 bit로 쉬프트 해서 연산한 결과 입니다.

그리고 여러 짓거리를 하고..
결국은 처음 API로 구현한 프로그램과 같은것이 EMPOS에 떳습니다.
배경 그림 ... 유성 떨어지는걸로 바꿧고...
마우스 클릭을, EMPOS 는 마우스가 없으니 터치 하면 격추한걸로 했고...
7-seg에 16진수로 맞춘 갯수를 표시하게 했고

적이 총 100여개 떨어지는데.. 100개 다 떨어지면 모니터상 (모니터닝 PC) 7-seg에 표시된 16진수를 10진수로 바꿔서 printf 하게 해놨습니다..

자세한건 아래 소스를 보시면...될거 같네요.. >_<;;

음...
main 이 picture_ex.c 파일입니다.
주석이 왜 영어냐면... 한글이 안써져서 입니다 ;;; 리눅스상.. 쩝..

중요 소스는..
// number 7-segment change function
unsigned char Getsegcode(int x)
{
 unsigned int code;
 switch(x)
 {
  case 0x0 : code = 0x3f; break;
  case 0x1 : code = 0x06; break;
  case 0x2 : code = 0x5b; break;
  case 0x3 : code = 0x4f; break;
  case 0x4 : code = 0x66; break;
  case 0x5 : code = 0x6d; break;
  case 0x6 : code = 0x7d; break;
  case 0x7 : code = 0x07; break;
  case 0x8 : code = 0x7f; break;
  case 0x9 : code = 0x6f; break;
  case 0xA : code = 0x77; break;
  case 0xB : code = 0x7C; break;
  case 0xC : code = 0x39; break;
  case 0xD : code = 0x5e; break;
  case 0xE : code = 0x79; break;
  case 0xF : code = 0x71; break;
  default  : code = 0; break;
 }
 return code;
}
숫자가 들어오면 해당 7-seg (디지털 숫자판의 각 led on off 비트 배열 숫자 입니다..)를 리턴하고...
음... 0에 대한 0x3f 값과  7에 대한 0x07 를 플래그로 하면 각각...  
0 :  8421 8421   | 7 : 8421 8421
      0011 1111   |     0000 0111  의 플레그 값이고 이걸 표로 하면

0 : 0x3f
   0 : on  
 5 : on   1 : on
  6 : off   
 4 : on   2 : on
   3 : on  

7 : 0x07   
   0 : on  
 5 : off   1 : on
  6 : off   
 4 : off   2 : on
   3 : off  
 음.. 뭐 대략 저런겁니다..

그림.. 이라 해봤자 적 케릭터 뿌리는 함수입니다.
void draw_image(int x, int y, int widht, int height, unsigned short *data)
{
 int n = 0;
 int i,j;

  for(j = y; j < height + y; ++j)
 {
  if(0 < y && y + height < LCD_HEIGHT)
  for(i = x; i< widht + x; ++i)
  {
   // draw image, but trancolor no draw
   if(0 < x && x + widht < LCD_WIDTH
    && enemy_data[n] != 0xF81F)
   {
    *(back_surface + (j*LCD_WIDTH + i)) = *(data + n);
   }
   ++n;
  } 
 }
}
빨간건, 투명색입니다.. 투명색이 아니거나 메모리 접근해선 안되는곳에 픽셀이 지정되면 그리지 않게 하는겁니다.

main 함수내.. 각 장치 초기화 및 메모리 접근 입니다..
 if( (fd_touch=open("/dev/touch", O_RDWR))<0 )
 {
  puts("device open fail");
  exit( 2 );
 }
 puts("init toutch!!");
 
 // set lcd system
 fd_lcd = open(FBDEVFILE, O_RDWR);
 if(fd_lcd < 0)
 {
  printf("Error fbdev open\n");
  exit(1);
 }
  
 // set lcd pointer
 real_surface =
  (unsigned short *) mmap(0, LCD_WIDTH * LCD_HEIGHT * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd_lcd, 0);
 puts("init lcd");

 // set 7-sement pointer
 for(i = 0; i< 2; ++i)
 {
  if((fd_led[0]=open("/dev/mem", O_RDWR | O_SYNC)) < 0)
  {
   printf("memory open fail\n");
   exit(1);
  }
  addr[i] = mmap(NULL, 1, PROT_WRITE, MAP_SHARED, fd_led[0], SEGADDR_1 + (0x00100000 * i));
 }
 puts("init 7seg");
 cnt = 0;
 print_7seg(cnt);
디버깅을 쉽게 하기 위해 초기화 완료되면 init 무엇 이라 했습니다.

다음..
while(Check_End())
 {
  tv.tv_sec = 0;
  tv.tv_usec = 10000;
  FD_ZERO( &rfds );
  FD_SET( fd_touch, &rfds );
  if( (judge = select(fd_touch+1, &rfds, NULL, NULL, &tv)) < 0 )
  {
   puts("select() fail");
   exit( 2 );
  }
셀렉입니다.. 음... 리눅스에선.. 소켓 뿐만 아니라 각 장치가 파일 시스템으로 (int)로 인식되므로 저런게 가능합니다.
대략.. 터치 스크린에 반응이 있으면 1 이상의 값이 judge로 저장 됩니다.. 만약.. -1 이 리턴되면 에러 겠죠

if( judge )
  {
   read( fd_touch, &p, 6 );
   if(p.flag == 0)
   {
    if(Check_Hit(p.x, p.y) == 0)
    {
     print_7seg(cnt++);
    }
   }
   
  // printf("\n(x,y,flag,byte) = (%.3d,%.3d,%d,%d)", p.x, p.y, p.flag, judge);
  }
  // output backscreen
  lmemcpy(back_surface, bg_data, bg_WIDTH * bg_HEIGHT * 2);
   
  // output enemy screen
  for(i=0; i<ENEMY_CNT; ++i)
  {
   if(Enemy[i].life == 1)
   {
    draw_image(Enemy[i].x, Enemy[i].y, enemy_WIDTH, enemy_HEIGHT, enemy_data);
    Enemy[i].y+=add;
   }
  }
  add > 30 ? add : add++;
  
  // copy to real lcd
  lmemcpy(real_surface, back_surface, LCD_WIDTH * LCD_HEIGHT * 2);
맨 윗부터.. 만약 반응이 있으면..... 이넘이 계속 눌려저 있는지 보고(치트 방지), 처음 눌려진거면, 해당 좌표 체크해서 7_seg의 숫자를 증가 시켜 갱신합니다.

다음... 반응이 있던 없던...
백스크린 버퍼에 배경 그림을 카피 하고
그 다음.. 적 스프라이트를 백 스크린 버퍼에 복사하고.
add 는... 떨어지는 속도 값입니다.. 처음에는 5만큰 떨어지다가 매순간 증감시켜서 30이 될때까지 증가 시키죠..
(즉 처음에 천천히 떨어지는 표적이 점점 일정 속도 까지 빨라지는겁니다..)

마지막에 이렇게 갱신된 백스크린의 그림을 리얼 스크린 (지금 LCD 포인터에 연결된 변수에..) 카피 합니다.

소스 자체는 간단하다고 생각되실지 모릅니다만..
리눅스 프로그래밍이라는것이.. vs 가 없어서.. vs에 찌든 사람들은 접근이 어렵지 않을까 생각되네요..
(디버깅 방법 이라던가... 리소스 켓치 라던가..)
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

어쩌다 보니 게임기란 게임기가 다 모였습니다.
NDS는.. 동생이 마리오 겜하니까...
PSP는... 졸업작품.. 반다이의 PSP게임 "스즈미야 하루히의 약속"의  얼굴표정 연구
           (이미지 와핑 기술 연구) 및 갖구 노는겸.. PMP겸으로 샀구요..
GP2X는.. 어떻게 하다보니 굴러 들어왔습니다. (F200 입니다)


NDS의 화면을 폈을때는.. 확실히 NDS가 겜 화면이 제일 넓어 보이는군요.

여기서 각각의 성능을 살펴 보죠

   CPU Memory  Video Ram  LCD 
 PSP  333Mhz  32MB  2MB   4.3 인치 (480 x 272)
 NDS  ARM9 (67Mhz)
 ARM7 (33Mhz) ?
 4MB  640KB  3인치 x 2 (256 x 192)
 (하단은 터치 가능)
 GP2X  ARM920T : host
 ARM940T : Video  
                 (200Mhz)
 64MB  ?  3.5인치 (320 x 240)
 F200 은 터치 가능

음... 우리나라의 GP2X 성능상은 NDS 와 PSP 중간쯤이 되는군요...
최근에 나온 GP2X F300 의 경우에는 CPU 성능이 533Mhz 인가 하는 .. 하여간 고성능으로 바꼈다는군요.

이제 각각의 전원을 켜봅니다.
음.. NDS는 뭔가 다이어리 같은 느낌이 나고
GP2X.. 좀 뭔가 부실한 느낌이 든다고 생각하시면.. 아직 제가 저거 사용한지 몇시간도 안되서 그럴껍니다 >_<;;
PSP.. 화려하죠.. 원래 배경은 저게 아닙니다 ;_;

 잠시 크기에 대해 비교해 보죠.
넓이는... PSP가 가장 넓습니다..
NDS.. 밑의 GBA 슬롯이 좀 거슬리는군요 ..

 두께입니다.
순서대로
PSP.. 신형이라 얇습니다...
NDS야... 반으로 접었으니 저렇지만.. 핀다면.. PSP보다 더 얇긴 하죠
GP2X.. AA 배터리 투입구 때문에 좌절.. orz (밑에 있는거 AA 배터리 칸입니다)
다행히.. F300 버젼은 AA 배터리를 버리고 리튬이온 같은 걸로 대체 하였기에..
실제 두깨는 신형 PSP 정도 입니다.

 세워서 가지고 놀 경우
PSP는 아머 케이스를 사용해야 세울수 있습니다.
GP2X는 터치펜을 받침대로 사용하여... 세울 수 있습니다.. 근데 좀... 힘듭니다 orz

 뒤에서 봤을때



자.. 그럼 테스트 해봅니다.
각각의 부팅 속도 입니다.
GP2X -> PSP -> NDS 순으로 부팅 시켰습니다.


GP2X 가장 먼져 켰는데 제일 오래 걸렸습니다. orz...
닌텐도 DS.. 제일 빠름니다.

위의 CPU 속도에 비하면 반대 결과 입니다.
(NDS : 67Mhz , GP2X : 200Mhz, PSP : 300Mhz)
아무래도.. OS 때문에 저런 속도 차이를 보이는게 아닐까 생각 되네요

재부팅도 한번 시켜보죠


재부팅을 하라니 PSP는 마치 PDA 처럼 바로 이전 상태로 rollback 하고
NDS와 GP2X는 처음부터 부팅하네요.

그나마 NDS는 부팅이라고 할만한게 없으니 그렇다 쳐도.. GP2X ㄷㄷㄷ

왜 이렇냐면. 안에 내장된 OS 때문이라 생각됩니다.
OS라면. 윈도우냐 도스냐 리눅스냐 그런거 생각하실지 모르시겠습니다만.. 그런 종류 입니다.
모든 컴퓨터 관련 기계는 OS가 중간에 껴서 소프트웨어와 하드웨어의 교신을 주고 받습니다.

NDS의 경우.. OS가 거의 없다고 추측됩니다.
왜냐면.. NDS 프로그래밍 할때, NDS 프로그램 시작 API 등을 등록해야 하기 때문이죠..

쉽게 말하면... PC에서 HelloWord 출력할때..
main()
{
  put ("hello world");
}
로 그냥 출력 하면 나오지만 NDS 는...

main()
{
   Init_NDS();                        // os 관련 오퍼레이터 초기화
   Init_VBL();                        // os 제어 환경 초기화
   put ("hello world");
}
식으로 프로그램 시작할떄 os 레퍼렌스를 초기화 시킨뒤 돌아가는 방식입니다....
그래서.. 부팅속도도 제일 빠르게 느껴지는거 같습니다.
(왜 NDS 게임을 할떄 맨처음 로고를 스킵하지 못하게 할까요? 그 사이 OS API 로딩 시키는.. 어찌보면 머리 너무 굴리는 닌텐도.)

PSP의 경우... 팜계열 OS (WinCE 같은 PDA계열 OS 입니다.) 가 아닐까 생각합니다.
왠지 PDA 처럼 전원 off 뒤 on 시키면 이전 작업 그대로 로딩 시키는것이..
소니의 경우.. 클리에(일명 리에짱... 리에짱 살려내 소니.. orz) 경험도 있으니
(그리고 리에짱 단종시키고 만든게 psp니까...)

GP2X의 경우... 뭐.. 모든 플렛폼에 잘 개조해서 넣을 수 있는 리눅스 기반입니다.
그러므로 일반 PC처럼 부팅 하는 시간이 좀 많이 생깁니다... orz

그렇다고 전용 OS 만들어 내라고 하던가... 하면 중소기업에서 돈이 없을테니 힘들테고...
NDS 처럼 프로그램 내에 os api 를 집어 넣으면 멀티 플렛폼을 표방하는
gp2x (mp3 나.. pmp 나 image 뷰어나.. 텍스쳐뷰어나..) 의 기능을 다 포기해야 할테니.. 그건 안되겠고..
게다가.. 개방 API 이므로 플밍하기 쉽게 만들려면... 어쩔 수 없는 선택인거 같습니다..


결론,
NDS : 여러 면에서 재미있는 물건이지만, 그만큼 프로그래밍 하기 짜증 난다.
PSP : 성능은 좋은데... 2D 프로그래밍은 아주 짜증난다는 소문, 현재는 PMP, 게임기 용도 사용
GP2X : 리눅스. 우려먹을꺼 다 우려 먹기, 현재는 PC 미연시를 포팅해서 들고 다님.  orz

신고

'임베이드 장비 > 임베이드 프로그래밍' 카테고리의 다른 글

PSP, NDS, GP2X 비교기  (2) 2008.10.01
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

Jlet에서의 encodeImage 란 함수가 있습니다.

Graphics 밑에 딸려 나온 것으로 역할은 이미지 데이터를 byte [] 뽑아줍니다.
음... 사용법에 대해선 전에 주의점으로 소개를 했지만 다시 써봅니다.

public static Image CopyImage(Image src)
{
  // 지금 들어오는 src를 바로  그래픽 받아오게 하면, 읽기 전용상태라 NullPointException이 발생한다
  // 이를 방지하기위해 Image copy본을 만든뒤 그 이미지를 encodeImage 하면된다.

  byte []temp = null;
  Image copy = Image.createImage(src);
  Graphics g = copy.getGraphics();
 
  temp = g.encodeImage(0, 0, src.getWidth(), src.getHeight());
  Image result = Image.createImage(temp, 0, temp.length);
 
  return result;
 }

C언어와 달리 들어오는 Image src 에 대해서 바로 접근이 안됩니다.
C언어라면, 함수가 호출되면서 Image src의 복사본이 오게 되겠지만, Java 문법상.. (아니 Wipi만 그런가?)
C 언어로 치면 Image CopyImage(const Image &src) 와 같이 들어오는거 같습니다.

참 비효율적이라고 생각 됩니다. 아니.. 내공이 부족한건지.. 하여간 윗 소스는
1. 받아온 Image의 Copy 를 생성한다.
2. 그 복사본 이미지에 대한 그래픽을 만든다.
3. byte [] temp 라는 배열 안에 복사본 이미지 전체 영역, (0,0)~(width, height)만큼 인코딩 시킨다
4. 가져온 temp byte 배열을 가지고 이미지를 생성한다. 생성하되, 시작 번지는 0 ~ temp 길이 만큼임

으로 생각하시면 됩니다..


왜 이렇게 하는건지는 잘 모르겠지만. 뭐 wipi가 그러니 그려러니 하는 수밖에 없죠.. 왠지 알면 알수록
꼬인다는 느낌이 Wipi입니다.. orz

하여간 이 encodeImage 저는 이미지에 대해 변화를 많이 주는 프로세싱을 하다 보니,
일반적으로
1. GetPixel 로 좌표의 RGB 알아낸다.
2. 이 RGB를 적당한 알고리즘으로 변형시킨다.
3. SetColor 로 RGB값을 지정한다.
4. SetPixel로 해당 좌표에 점을 찍는다…

를 하기엔, 퍼포먼스가 너무 딸리게 됩니다. 돌아가는 환경이 PC로 치면 386,486급을 달리고 있고,
거기에 어셈만큼 빠른 C언어가 아닌 Java… 버추얼 PC를 통해서 느린 판국에 Class 개념의 객체 지향은
일반 C언어의 순차적 언어에 비하면 많이 느리죠
(모바일 경우.. 뭐 어떻게 뜯어 고쳐서 Jlet도 Clet에 비하면 80%정도 성능을 낸다고 합니다만.. 음…)

하여간, MFC의 (비교대상이 되려나..) GetPixel, SetPixel 를 사용하면 최신 듀얼 CPU 컴퓨터도 버벅이는 상황에서
모바일이라고 별수 있나요.. 그래서 GetPixel, SetPixel 을 사용하지 않고 이것을 배열에 다 넣은뒤
이 배열 값을 조작한 다음 다시 나중에 이미지 만들면 되겠다 싶어서 encodeImage에 대해 파게 됬습니다.. orz

우선 들어가기 앞서 Wipi Jlet API 에선 뭐라고 설명하는지 살펴 봅니다.

encodeImage
public byte[] encodeImage(int x, int y, int w, int h)

화면의 특정 영역을 BMP 포맷으로 인코딩한다. 인코딩된 BMP 포맷은 바이트 어레이로 반환되며 파일로 저장하거나 다시 이미지 생성에 이용할 수도 있다.

Parameters:
x - 인코딩할 영역의 시작 x 좌표
y - 인코딩할 영역의 시작 x 좌표
w - 인코딩할 영역의 폭
h - 인코딩할 영역의 폭

Returns:
인코딩된 BMP 포맷의 바이트어레이, 인코딩에 실패하면 null

Throws:
java.lang.IllegalArgumentException - 대상 영역의 일부가 Graphics의 범위를 벗 어나는 경우 또는 w, h가 음수인 경우

출처 : http://www.developerzone.co.kr/release/wipi/SKT_WIPI_JAVA2.0_API/org/kwis/msp/lcdui/Graphics.html#encodeImage(int,%20int,%20int,%20int)

음….. 화면 특정 영역을 BMP포멧으로 인코딩이라고 되있습니다.
여기서 햇갈리는게.. BMP포멧이 뭘까요?
BMP 포멧에 대해선 BMP 구조에 대해 알아야 하는데, 일반적인 BMP는 MS에서 만든 그거겠죠… 라고 생각하다가 조금 고생했습니다..
우선 BMP가 크게 header + (8bit 이하 그림이면) palettle +pixel data 로 구성 되있죠.

처음엔 그냥 BMP 포멧이라 하길래 BGR 값으로 byte 가 쫙~~~~~~~~~ 뽑힐줄 알았는데…
앞에 Header가 있더군요. Orz 일단 Header size 부터 알아냅시다..

System.out.println(src.getWidth()+"x" + src.getHeight() + "Imaghe bytes are " + temp.length);

System.out.println("pixel total number : " + src.getWidth()* src.getHeight());

System.out.println("header size : " + (temp.length - (src.getWidth() * src.getHeight()*3)));

System.out.println();

위 소스를 보면 이미지의 넓이, 높이에 대한 인코딩 추출 byte 길이가 나오고,
실제 이미지에 쓰인 픽셀이 몇 개인지 (해상도라고 하죠 보통..) 출력하고
header 사이즈에 대해 출력됩니다.

저기에 보면 temp 전체 길이에 대해서 픽셀 숫자의 3배수를 뺍니다.
여기서 혼동이 되는게 BMP 포맷은, 1픽셀을 4byte 로 표현합니다, AABBGGRR 로 구성되어있죠
하지만 Wipi 상 BMP 포맷은 RRGGBB 3byte 입니다.

가끔 MSDN 이 좋다고 느껴지는게, 조금 복잡하거나 생소한 API경우 예제 소스를 같이 포함해서 사용법에 대해 나와있는데
Wipi경우 이건 뭐 API만 쑥 던져주고 알아서 삽질하셈 인건지 뭔지… orz

하여간 저렇게 해서 header size를 알아냈으니 그 이후 픽셀부터 수정하면 될까요…?
정답은 꼭 그렇지는 않다 입니다..

허나 대부분은 저렇게 해서 나온 size 에서 + a 지점부터 x,y좌표 계산한 번지의 byte 숫자를 바꾸면 이미지 색이 바뀜니다.
alpha 값은… 저도 많이 삽질했지만 특별한 규칙이 있는건지 없는건지;;;
alpha 값은… header + 특정변수 의 변경값이 0,0의 픽셀을 변하는 곳이.. alpha값입니다.. (이 뭐 무책임한.. orz)
즉, 결론은... 저런거 삽질 할 시간에 차라리 int 같은 배열로 뽑아서 관리 하는게 훨~~~ 씬 편합니다.
int 로 어떻게 뽑냐면..
static int[] CraeteArrayImage(Image srcImg)
 {
      Image copyImg = Image.createImage(srcImg);
      Graphics g = copyImg.getGraphics();
   
      int[] arrayImg = new int[srcImg.getWidth()*srcImg.getHeight()];
 
      int bpp = 32;// getDisplay().getBitsPerPixel();
      int bpl = (srcImg.getWidth() * bpp + 7) / 8;
      g.getRGBPixels(0, 0, srcImg.getWidth(), srcImg.getHeight(), arrayImg, 0, bpl);
      return arrayImg;
 }
이렇게 해주시거나..
아니면...

static int[] CraeteArrayImage(Image srcImg)
 {
      Image copyImg = Image.createImage(srcImg);
      Graphics g = copyImg.getGraphics();
   
      int[] arrayImg = new int[srcImg.getWidth()*srcImg.getHeight()];
      int cnt = 0;
      for(int y=0; y < copyImg.getHeight(); ++y)
      {
           for(int x=0; x < copyImg.getWidth(); ++x)
          {
                 arrayImg[cnt++] = g.getPixel(x, y);
           }
       }
 
       return arrayImg;
 }
물론... int 는 4byte... 그림 RGB만 차지하는 byte는 3byte 이므로 불필요한 공간 25%가 더 쌓이는 코드입니다.
저걸 byte로 바꿔서 코딩하면.. 금방 될껍니다 ^^;

신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

 public static Image CopyImage(Image src)
 {
  // 짐 들어오는 src를 바로  그래픽 받아오게 하면, 읽기 전용상태라 NullPointException이 발생한다
  // 이를 방지하기위해 Image copy본을 만든뒤 그 이미지를 encodeImage 하면된다.
  byte []temp = null;
  Image copy = Image.createImage(src);
  Graphics g = copy.getGraphics();
 
  temp = g.encodeImage(0, 0, src.getWidth(), src.getHeight());
  Image result = Image.createImage(temp, 0, temp.length);
 
  return result;
 }

음.. 하여간 Image copy를 써야 한다는점 체크
참고로. encodeImage 하면, 이미지 전체를 (헤더, 팔레트, 맵 등..)을 가져오는거 같다.
맵만 가져오는줄 알고 작업하다 낭패 봤음.. orz
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

Tag Java

티스토리 툴바