# 바이트 배열에 저장된 DIB정보를 DIB메모리 블럭 만들기
2007년 3월 31일
울산대학교 PSLab 이태호
http://www.soulfree.net
혹시나 퍼가실땐 위의 내용을 꼭 추가해 주세요~
==================================================================================================

우선 알아보기 어려운 이 글의 제목부터 장황하게 설명 하도록 하겠습니다. ^^;;
이 글의 제목은 위에서 보고 클릭하셨다시피 "바이트 배열에 저장된 DIB정보를 DIB메모리 블럭 만들기"입니다.
제 블로그의 졸업작품 카테고리를 보셔서 아시겠지만, DIB는 Device Independent Bitmap의 약자로
장치에 의존적이지 않는 비트맵이라는 뜻입니다.

(세상에는 여러 종류의 운영체제가 존재하고 그런 운영체제 중에서도 Graphic User Interface를 지원하는
운영체제가 많이 배포되고 운영되고 있습니다.
따라서 그런 GUI운영체제들은 자신만의 색깔 코드를 가지고 있어서, 그림을 보여줄때 자신만의 코드를 사용하여
보여주기도 합니다. (저의 추측이 섞였습니다...) 그렇게 보여주는 비트맵 형식이 바로 DDB입니다.
Device Dependent Bitmap이라고 하고요...
DIB 형식은 그와 다르게 비트맵에 색상정보가 들어가 있습니다. 따라서 어떤 운영체제든지 장치든지 같은
그림을 보게 되는 것이고, DDB는 장치에 의존적이어서 운이 나쁘면 서로 다른 그림을 보게 됩니다.)

이번 졸업 작품에는 클라이언트나 서버로 부터 전송받은 바이트 배열에서 비트맵 부분을 추출하여 보여주도록하는 내용을 포함하게 되었습니다. 그런데 이때 전송하는 내용은 DIB 형식의 비트맵입니다.

바이트 배열은 8비트씩 1바이트로 길게 열을 지어 늘어진 녀석입니다.
그리고 DIB의 경우에는 BITMAPFILEHEADER 구조체부터 시작해서 BITMAPINFOHEADER 구조체와 RGBQUAD
구조체 배열
, 그리고 비트맵 내용들로 구조가 이루어져 있습니다.
이런 DIB를 이루는 구조체의 내용은 제 블로그를 잘 보시면 쉽게 아실 수 있고,
제가 여기서 설명 드리고 싶은 것은 DIB를 이루는 구조체 변수를 만들고
그 구조체 변수에 해당하는 크기의 메모리를 할당하여
바이트 배열에 저장된 DIB내용을 그런 구조체에 저장하는 순서를 보여 드리는 것입니다.

즉, 단지 바이트 배열 형태인 장치 독립적인 비트맵 정보를 장치 독립적인 비트맵 정보인 DIB 형태로
변환하는 과정입니다.
그림으로 나타내어 보겠습니다.

사용자 삽입 이미지

=============바이트 배열을 DIB 형식으로 저장하기=====================

1)DIB구조중에 가장 먼저 시작되는 BITMAPFILEHEADER 구조체에 값을 할당하는 과정입니다.
//DIB 내용이 저장된 바이트 배열의 이름은 byteImage[]입니다.

int j = 0; <- 요 변수는 바이트 배열의 인덱스로 사용할 녀석입니다.

//BITMAPFILEHEADER 구조체의 공간을 할당합니다.
BITMAPFILEHEADER* bf = (BITMAPFILEHEADER *) malloc(sizeof(BITMAPFILEHEADER));

//바이트 배열에 저장된 BITMAPFILEHEADER 내용을 방금 생성한 bf에 저장합니다.
//실제로는 바이트 배열에서 BITMAPFILEHEADER 내용이 시작하는 부분의 주소를 저장하는 것입니다...
bf = (BITMAPFILEHEADER*) byteImage; <- 이렇게 하면 byteImage배열에서 bf에 할당한 메모리 크기만큼만
bf에 저장되겠지요.

//바이트 배열의 인덱스를 계산합니다.
j = sizeof(BITMAPFILEHEADER); <- 위에 제가 그린 그림을 참조하면 j 변수는 24가 저장되겠지요.

2)다음으로 BITMAPINFOHEADER 구조체에 값을 할당하는 과정입니다.

//BITMAPFILEHEADER 구조체의 공간을 할당합니다.
BITMAPINFOHEADER* bmih = (BITMAPINFOHEADER *) malloc(sizeof(BITMAPINFOHEADER));

//바이트 배열에 저장된 BITMAPINFOHEADER내용을 방금 생성한 bf에 저장합니다.
//이것 역시 실제로는 바이트 배열에서 BITMAPFILEHEADER 내용이 시작하는 부분의 주소를 저장하는 것입니다...
bmih = (BITMAPINFOHEADER*) (byteImage + j);
//바이트 배열의 인덱스를 계산합니다.
j += sizeof(BITMAPINFOHEADER); <- 그림을 참조하면 j 변수는 104가 저장되겠지요.

3)다음으로 RGBQUAD 구조체 배열에 값을 할당하는 과정입니다.

** 여기서 잠깐!!***---------------------------------------
이 글을 참조하시면 잘 아시겠지만 RGBQUAD 배열의 크기는 정해져 있지 않습니다.
RGBQUAD는 팔레트 정보를 담고 있는 배열로써
DIB의 내용이 트루컬러의 경우는 4, 그외 8색이면 4 * 8, 16색은 4 * 16, 4 * 256은 256색을 표현할때의 RGBQUAD 구조체 배열의 크기가 됩니다. 단위는 바이트...
따라서 경우에 따른 if, else 문으로 나누어 주어야합니다.
또한 바이트 배열에 저장된 DIB의 RGBQUAD 배열의 크기는 BITMAPINFOHEADER 구조체 맴버변수인
biClrUsed에 저장되어있습니다. 다만 트루컬러의 경우 4가 저장되어야 하나 0이 저장된다고 하는군요.
--------------------------------------------------------

 RGBQUAD* rgbq;
//DIB의 내용이 트루 컬러일때가 아닐 때 입니다.
 if(bmih->biClrUsed != 0){

//메모리 공간을 할당하고
  rgbq = (RGBQUAD*) malloc(bmih->biClrUsed);

//주소를 복사한 뒤(즉, RGBQUAD의 내용을 바이트 배열에서 추출한 뒤)
  rgbq = (RGBQUAD *)(rfbImage + j);

//인덱스를 다시 계산합니다.
  j += sizeof(RGBQUAD) * bmih->biClrUsed;
 }


//트루 컬러일때입니다.
 else{
  rgbq = (RGBQUAD*) malloc(sizeof(RGBQUAD));
  rgbq = (RGBQUAD *)(rfbImage + j);
  j += sizeof(RGBQUAD);
 }

4)다음으로 BITMAPINFO 구조체에 값을 할당하는 과정입니다.
BITMAPINFO 구조체는 이 글을 참조하시면 아실 수 있듯이 BITMAPINFOHEADER 구조체와 RGBQUAD 구조체 배열을 그저 묶은 구조체입니다. 따라서 왜 만드는지 반문 하실 분들이 계실겁니다.
이 과정은 CreateDIBitmap() 함수를 사용해 DIB 메모리 블럭을 만들때
CreateDIBitmap() 함수가 BITMAPINFO 구조체의 주소를 매개변수로 입력받기 때문입니다.

//j 변수에는 BITMAPFILEHEADER와 BITMAPINFO 크기(BITMAPINFOHEADER 크기 + RGBQUAD[] 크기)가
// 저장된 값이 들어가 있을 것입니다.
//따라서 j의 값에 BITMAPFILEHEADER를 빼주면 BITMAPINFO 크기를 얻을 수 있겠죠.
 BITMAPINFO* bmi = (BITMAPINFO*) malloc(j - sizeof(BITMAPFILEHEADER));

//이것 역시 RGBQUAD 구조체 배열때문에 나누어 주어야합니다.
//트루 컬러가 아닐 때입니다.
for(i = 0; i < bmih->biClrUsed; i++){
 bmi->bmiColors[i] = rgbq[i];
}

//트루 컬러 일 때 입니다.
if(bmih->biClrUsed == 0)
  bmi->bmiColors[0] = rgbq[0];

//BITMAPINFOHEADER는 그냥 집어넣어주면 되겠죠
bmi->bmiHeader = *bmih;

5)다음으로 실제 비트맵 데이터를 임시 바이트 배열에 할당하는 과정입니다.
이 과정역시 CreateDIBitmap() 함수를 사용해 DIB 메모리 블럭을 만들때
CreateDIBitmap() 함수가 바이트 배열로 된 실질적인 비트맵 정보를 매개변수로 입력받기 때문입니다.

 char *pixels = (char*) malloc(len - j);
 for(i = 0; i < len - j; i++){
  pixels[i] = rfbImage[i+j];
 }

6)마지막으로 메모리 블럭을 만듭니다.
HDC hdc = GetDC(m_hwnd);
HBITMAP hbm; //저장될 메모리 블럭
 
hbm = CreateDIBitmap(hdc, &(bmi->bmiHeader), CBM_INIT, pixels, bmi, DIB_RGB_COLORS);

매개변수를 설명하자면
(윈도우 핸들러, BITMAPINFOHEAD의 주소, 초기화 상수, 바이트 배열 형식의 실제 비트맵 정보, BITMAPINFO , 컬러 정보 상수)


결론~~
이렇게 바이트 배열에 담겨있는 DIB 정보를 추출하여 실제로 사용가능한 DIB형식으로 만들어 내는 과정을 기술하여 보았습니다. 상당히 난잡하고 메모리 낭비가 있는 과정일지도 모르니, 이글을 보시는 고수님들께서는 과감히 댓글을 부탁드립니다...
사실 이 과정을 알아내고 이해하는게 조금 힘이 들었는데 (약 하루, 이틀 소요가 되었으니까요...)
바이트 배열에서 DIB 형태로 변환하는 문서가 일목 요연하게 나와있는게 없어서 그랬습니다.

이런 과정을 시도한 사람은 저뿐이었는지도?? ㅠㅠ

조만간 졸업작품과 연계하여 쓰고 있는 저널논문의 내용을 요약해서 글 쓰도록 하겠습니다.

'Projects > CoVNC' 카테고리의 다른 글

MSXML 사용법 요약  (0) 2007.05.05
Microsoft XML Core Service(MSXML)  (0) 2007.05.05
C++을 사용해 바이트 배열에 저장된 DIB정보를 DIB메모리 블럭 만들기  (2) 2007.03.31
DIB/DDB 구조  (0) 2007.03.30
CListBox  (0) 2007.02.21
부요리눅스의 클립보드  (0) 2007.02.20

DIB/DDB 구조

Projects/CoVNC 2007.03.30 18:01 Posted by soulfree >동네청년<

비트맵은 그림을 컴퓨터에 저장하기 위해 그림을 구성하는 각 점의 색상값을2차원
배열의 형태로 저장하는 포맷의 일종이다. 이 방식은 마이크로소프트가윈도우에서
처음소개하였다. 물론그림을컴퓨터에저장하고표현하는방식에는비트맵방식이
외에도G I F, J P G와 같은 여러 가지다른 방식이 있지만, 비트맵을제외한다른그래
픽 포맷은 압축되어있기때문에프로그램에서빠른속도로 처리하거나이미지를가
공하기가힘들다.
비트맵은 압축되지 않은 형태이므로비록 용량을 많이 차지하고 있지만 가공하기가
유리하고화면에직접 출력될수있는 장점이있어 기본그림 파일형식으로 많이사
용되고있다.
비트맵 구조와 종류
비트맵은말그대로여러개의비트(b i t)가하나의맵(m a p)을이루고있다. 즉, 그림을
구성하는픽셀정보는2차원배열의형태로저장되어있다. 그래서비트맵은픽셀색
상, 이미지의위치와크기, 해상도등의정보를가지고있는데이터구조를갖고있다.
게임프로그래밍에서는그래픽이미지가다른부분보다중요한데, 게임에서사용되는
복잡한이미지는SetPixel,LineTo,Rectangle,Ellipse 와같은그리기함수를이용하
여 그리는것보다 비트맵이미지를이용하여그리는것이 훨씬 효율적이고생산적이
기때문이다.


비트맵
여기에서는비트맵의구조와종류에대해알아보고각비트맵의종류별특징을비교해본다.

마지막으로장치종속적 비트맵을이용하여비트맵을화면에그리는예제를작성해볼것이다.
■ 비트맵구조와종류

■장치 종속적비트맵과장치 독립적비트맵
■ 비트맵파일을화면에 그리는간단한예제


비트맵을 사용하면 이미지데이터의양이 많기때문에실행파일의크기가커지며

메모리를 많이 사용하는단점이있지만그단점에비 해적은CPU 부담으로정밀한묘사
가가능하고처리과정이간단해지는장점이있다.
그렇다면게임에서필수적으로 사용하는 비트맵의 종류와 구조에대해서알아보자.
장치 종속적 비트맵과 장치 독립적 비트맵
윈도우 CE는 비트맵 형식으로 장치 종속적 비트맵(DDB, Device Dependent
B i t m a p)과장치독립적비트맵(DIB, Device Independent Bitmap)을지원하고있다.


장치종속적비트맵은현재시스템의디스플레이가직접처리할수있는비트맵을말
한다. 그래서비트맵을이루는픽셀의형식과배열은디스플레이의것과동일하다. 따
라서 별도의 변환 과정 없이 비트맵은 시스템의 디스플레이에바로 전송될수 있다.
그러나장치 종속적 비트맵은현재 시스템의디스플레이장치가가지고있는 부가적
인 정보(팔레트, 픽셀포맷등)를 따로 보관하지않기 때문에다른 종류의 디스플레이
장치에서는정확하게출력되지않는단점이있다.
장치 독립적 비트맵은 시스템의 디스플레이 장치와 상관 없이 비트맵을 출력하는데
필요한 모든정보(팔레트, 픽셀포맷등)를가지고 있는비트맵이다. 따라서어떠한종
류의디스플레이하드웨어에서도동일한모습의비트맵을출력할수있다. 그러나특
정 디스플레이하드웨어의구성이장치 독립적 비트맵의구성과다르다면적절한픽

"여기서잠깐
GDI의 그리기함수
GDI 그리기 함수에는 점을 찍는 SetPixel() 함수, 선을 그리는 LineTo() 함수, 사각형을 그리는 Draw3DRect(), FillRect() 함수, 타원을그리는Ellipse() 함수등이있다.
그럼, 이함수를이용하여 삼각형모양 을 간단하게그려본다고생각해보자. GDI에는삼각형그리기함수가없기때문에 삼각형은 LineTo( ) 와MoveTo( ) 함수를여러번호출해서그려야한다. 그리고 삼각형의색을 칠하기 위하여 복잡한 연산을 거쳐야 한다. 하지만비트맵 이미지로 삼각형 그림을 가지고 있으면 이러한 복잡한과정없이쉽게그림을화면이그릴수있다.
여기에서는 간단한 삼각형을가지고예를 들었지만게임에서는삼각형보다훨씬 복잡한 그림이 많이 나온다. 이러한그림을항상 GDI 의그리기함수로그린다고생각하면끔직한일이아닐수없다."



셀 포맷의변환작업이 필요하고 팔레트에해당하는색상을 매핑시켜야하는 부담이
있어, 비트맵의출력속도가떨어질수있는단점이있다.
표면적으로보았을때에는장치독립적비트맵( D I B)이장치종속적비트맵(D D B)보다
훨씬 성능이 좋은 포맷이고D I B가 D D B보다 최신 포맷이다. 하지만아직까지는두
가지포맷모두사용해야하므로어느하나를선택할수는없다. 예를들어, D I B가장
치 독립적이고 최신 포맷이긴 하지만 디바이스 컨텍스트(Device Context)에 선택될
수있는비트맵은D D B뿐이고프로그램내부에서의생성과파괴작업도D D B가훨씬
효율적이다. 그래서두가지 포맷의특징을모두 알고 있어야하며 상호변환 방법에
대해서도알고있어야한다.


장치종속적비트맵
먼저장치종속적비트맵에대해알아보자. DDB 구조는다음과같다.
typedef struct tagBITMAP {
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP;


• b m T y p e 은비트맵타입이지만항상0이다.
• b m W i d t h 와 b m H e i g h t 는 실제 비트맵 이미지의 폭과 높이다. bmWidthBytes는
bitmap 이미지의한줄에표현될바이트수인데비트맵은word 단위로기록되므로
b m W i d t h B y t e s 는항상짝수다.
• b m P l a n e s 는색상면의개수다.
• b m B i t s P i x e l 은한픽셀에필요한비트의개수다.
• b m B i t s 는실제비트맵데이터를가리키는포인터다. 단, bmBits는반드시c h a r a c t e r
배열, 즉1 바이트배열의포인터이어야한다.


DDB는 CreateB i t m a p() 함수로도쉽게만들수있다. 이함수는간단한장치종속적비
트맵을만들어주는역할을한다. 성능적인측면을고려해볼때, 대체로 CreateBitmap()
함수는 흑백 비트맵을 만들 때 주로 사용하고, 컬러 비트맵을 만들 때에는
CreateCompatibleBitmap()
함수를사용한다. 그이유는C r e a t e B i t m a p() 함수로만들어
진비트맵은S e l e c t O b j e c t() 함수로D C에선택할때속도가느리기때문이다.
그럼C r e a t e B i t m a p() 함수를살펴보자.

HBITMAP CreateBitmap(
int nWidth,
int nHeight,
UINT cPlanes,
UINT cBitsPerPel,
CONST VOID *lpvBits );


이함수가호출되면리턴값으로비트맵, 즉DDB 핸들이리턴된다.
또한CreateCompatibleBitmap() 함수로도DDB를 만들 수 있다. 이함수는hdc를
인자로받아서디바이스컨텍스트와픽셀포맷, 색상수가동일한빈비트맵을만들어
준다.

, 이함수로만들면비트맵의각픽셀은초기화되지않는다.
함수의원형은다음과같다. 주의해서보아야될부분은CreateCompatibleBitmap()
인데, 이함수는 인자로디바이스컨텍스트를받는다. 그이유는SelectObject() 함수
를이용하여 비트맵을DC로 선택할때 빠른성능을내기때문이다.
HBITMAP CreateCompatibleBitmap(
HDC hdc,
int nWidth,
int nHeight );

• nWidth, nHeight는이미지의폭과높이다.
• c P l a n e s 는장치에있는색상면의수이며반드시1이어야한다.
• c B i t s P e r P e l 은픽셀의색상을결정하기위한필요한비트수다.
• l p v B i t s 는비트맵데이터이고반드시워드(2 바이트) 배열로이루어져야한다.
• h d c에는디바이스컨텍스트의핸들을넣어준다.
• n W i d t h 와 n H e i g h t 에는비트맵의폭과높이를설정한다.


이렇게만들어진비트맵은 SelectObject() 함수를통해 메모리디바이스컨텍스트에선택되며해당디바이스컨텍스트에대한 GDI함수는 선택된 비트맵에그려지게된다.
사용이끝난비트맵은DeleteObject() 함수를호출하여제거할수있다.


장치독립적비트맵
다음은 장치 독립적 비트맵의 구조에 대해서 알아보자. DIB는 크게 BITMAPFILEHEADER 와

BITMAPINFO 그리고 비트맵이미지데이터로 이루어져 있다.
 

사용자 삽입 이미지




typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;


• bfType 은 이 파일이 비트맵인지를 식별할 수 있도록 두 바이트로 표시해 두는 것
이며반드시 BM(0x42,0x4d) 이어야한다. bfSize는 비트맵파일의크기다.
• bfReserved1, bfReserved2는 예약되어 있는 값이고 0으로 설정되어 있다.
bfOffBits 는 실제 비트맵 데이터 값과 헤더의 오프셋 값이다. 즉, 이 값은
BITMAPFILEHEADER 와 BITMAPINFO 의 크기다.


BITMAPINFO 구조체는 BITMAPINFOHEADER 구조체와 RGBQUAD 구조체로
이루어져있는데먼저BITMAPINFOHEADER 구조체를살펴보면다음과같다.


typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;

• biSize 는 BITMAPINFOHEADER 구조체의크기를 나타낸다.
• biWi d t h 는비트맵의가로픽셀수, biHeight는비트맵의세로픽셀수다.
• b i P l a n e s 는장치에있는색상면의개수이며 반드시1 이어야한다.
• b i B i t C o u n t 는한픽셀을표현할수있는비트수다.
• b i C o m p r e s s i o n 은 압축 형태를 지정한다. BI_RGB는 압축되지 않은 비트맵이고
BI_RLE8 은8 비트압축, BI_RLE4는4 비트압축을뜻한다.
• b i S i z e I m a g e 는 실제 이미지의 바이트 크기이며 압축되지 않은 비트맵일 경우에는
0이다.
• biX elsPerMeter 는미터당가로픽셀수다.
• biYPelsPerMeter 는미터당세로픽셀수다.
• biClrUsed 는색상테이블의색상 중 실제로 비트맵에서사용되는 색상수를 나타낸
다. 이값이 0이면 비트맵은사용할 수 있는모든색상을사용한다. 이값이 0이아
니라면 RGBQUAD 구조체배열의크기는 이멤버값만큼된다.
• iClrImportant 는 비트맵을 출력하는데 필수적인 색상수를 나타내며 이 값이 0이면
모든색상이 다 사용되어야한다.
RGBQUAD 구조체는다음과같이이루어져있다.
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;


우선다음의GDI 함수를알아보고코드를살펴보자.
CreateCompatibleBitmap( ) 함수
HBITMAP CreateCompatibleBitmap(HDC hdc, int nWidth, int nHeight );

• 이 함수는디바이스 컨텍스트와 호환되는, 즉픽셀 포맷과 색 상수 등이 같은 비트
맵을 만드는데 CreateBitmap( ) 함수처럼 비트맵 이미지 데이터를 초기화할 수는
없다. 단순히폭과높이만설정할수있다.
• 함수를사용한후에는반드시DeleteObject() 함수를호출해야한다.


CreateCompatibleDC( ) 함수
HDC CreateCompatibleDC(HDC hdc );

• 이 함수는 장치의 디바이스 컨텍스트와 호환되는디바이스 컨텍스트, 즉 메모리디바이스 컨텍스트를만든다. 비트맵을 디바이스 컨텍스트에 선택할 때 이 함수를 이용하여 메모리 dc를 만들어 선택한다. 사용한 후에 반드시 DeleteDC() 함수를 호출한다.
• hdc 인자로N U L L을전달할때에는디폴트로현재디스플레이화면의디바이스컨
텍스트와호환되는디바이스컨텍스트핸들을반환하게된다.

SelectObject () 함수
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj );

• 이 함수는 디바이스 컨텍스트에GDI 객체를선택할수 있게 한다. GDI 객체란펜이
나 브러시, 폰트, 비트맵 등을 말하는데 여기에서는 비트맵을 디바이스 컨텍스트에
선택하기 위해서 사용한다. GDI 객체는반드시 디바이스 컨텍스트에 선택되어진후
사용되기때문에GDI 객체를사용할때에는반드시이 함수를사용해야된다. 이함
수를 사용하면 반환 값으로 선택되기 전의 GDI 객체가반환되는데이 값을 받아 두
었다가 GDI 객체를사용한 후, 반드시 디바이스 컨텍스트에 이전 GDI 객체를 선택
한다.


BitBlt() 함수

BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop );

• DDB를 뿌리는데 가장 유용한 이 함수는 내부적으로 그리려는 타깃과 소스의 픽셀
포맷이 다르면 타깃의 픽셀 포맷에 맞게 픽셀 포맷을 변환하여 뿌린다. 또한
dwRop 인자에의해서여러가지로그릴 수도있다. 여기에서는 SRCCOPY 를 사용
해단순히타깃에원본을복사했다.

'Projects > CoVNC' 카테고리의 다른 글

Microsoft XML Core Service(MSXML)  (0) 2007.05.05
C++을 사용해 바이트 배열에 저장된 DIB정보를 DIB메모리 블럭 만들기  (2) 2007.03.31
DIB/DDB 구조  (0) 2007.03.30
CListBox  (0) 2007.02.21
부요리눅스의 클립보드  (0) 2007.02.20
Virtual Network Computing  (0) 2007.02.14

CListBox

Projects/CoVNC 2007.02.21 14:53 Posted by soulfree >동네청년<

2005/04/28 09:30

http://blog.naver.com/asf99/80012365410

1) AddString("문자열");  file://리스트 박스에 문자열 추가

2) DeleteString(index);   // Index번쨰 것을 선택

3) GetCount();    file://전체 항목 갯수 구함

4) GetSelCount();  / 선택 항목 갯수

5) GetSel          file://선택된것인지 양수 음수 체크

6) GetText(int,문자열)  --int(index)번쨰 문자열을 문자열 변수에 할당

7)Resetcontent()   /list내용 모두삭제


'Projects > CoVNC' 카테고리의 다른 글

C++을 사용해 바이트 배열에 저장된 DIB정보를 DIB메모리 블럭 만들기  (2) 2007.03.31
DIB/DDB 구조  (0) 2007.03.30
CListBox  (0) 2007.02.21
부요리눅스의 클립보드  (0) 2007.02.20
Virtual Network Computing  (0) 2007.02.14
클립보드의 정의  (0) 2007.02.14

부요리눅스의 클립보드

Projects/CoVNC 2007.02.20 15:43 Posted by soulfree >동네청년<

자연스러운 Cut/Paste 환경 지원
윈도우 환경에서는 Cut/Paste가 일관성있게 동작하고 데이터 교환이 제대로 이루어지지만, X윈도우 환경 하에서는 표준이 없어서 Cut/Paste가 제대로 이루어지지 않는다. 부요 데스크탑에서는 X윈도우 환경 하에서 응용 프로그램끼리 Cut/Paste가 자연스럽게 이루어지면서 데이터 교환을 원활히 할 수 있도록 했다. 이 사업에서 개발되고 있는 클립보드 프로그램 이름은 Bclipboard라 이름붙였다. Bclipboard 구조는 <그림 5>와 같으며, 클립보드 동작에 필요한 주요 요소들은 다음과 같다.

◆ 클립보드 서버 : MS에서는 데이터의 보관을 OS 레벨에서 하지만, X윈도우에서는 응용 프로그램끼리 데이터를 주고받아야 한다. Cut한 응용 프로그램이 종료하면 그 데이터도 따라서 사라지게 된다. 이를 방지하기 위해 응용 프로그램의 종료 뒤에도 데이터를 보관해 주는 서버가 필요하다.
◆ 이력 관리기 : 클립보드 데이터의 히스토리를 보관하고 이를 관리한다.
◆ 클립보드 제어 : X윈도우 환경에서의 클립보드에는 owner와 requestor가 존재하기 때문에 owner와 requestor간 데이터를 제어한다.
◆ 데이터 교환 포맷 : 부요 데스크탑에서는 응용 간 데이터 변환을 위해 XML를 사용한다.

기존의 공개 소프트웨어인 Gcm, Klipper, Gclipboard와 BClip board를 <표 2>와 같이 비교해 보았다.

'Projects > CoVNC' 카테고리의 다른 글

DIB/DDB 구조  (0) 2007.03.30
CListBox  (0) 2007.02.21
부요리눅스의 클립보드  (0) 2007.02.20
Virtual Network Computing  (0) 2007.02.14
클립보드의 정의  (0) 2007.02.14
Ultra VNC 소개  (0) 2007.02.13

Virtual Network Computing

Projects/CoVNC 2007.02.14 17:04 Posted by soulfree >동네청년<

Virtual Network Computing

From Wikipedia, the free encyclopedia

(Redirected from Vnc)
Jump to: navigation, search

Virtual Network Computing (VNC) is a desktop sharing system which uses the RFB (Remote FrameBuffer) protocol to remotely control another computer. It transmits the keyboard presses and mouse clicks from one computer to another relaying the screen updates back in the other direction, over a network.

VNC is platform-independent ? a VNC viewer on any operating system can connect to a VNC server on any other operating system. There are clients and servers for almost all operating systems and for Java. Multiple clients may connect to a VNC server at the same time. This technology's popular uses include remote technical support, and accessing files on one's work computer from one's home computer.

VNC was originally developed at AT&T. The original VNC source code and many modern derivatives are open source under the GNU General Public License.

Contents

[hide]

[edit] History

VNC was created at the Olivetti & Oracle Research Lab, which was then owned by Olivetti and Oracle Corporation. In 1999 AT&T acquired the lab, and in 2002 closed down the lab's research efforts.

The name originates from a thin client asynchronous transfer mode (ATM) network computer called the Videotile, which was essentially an LCD with a pen input and a fast ATM connection to the network. VNC is essentially a software-only version of this "ATM Network Computer".

Developers who worked on VNC while still at the AT&T Research Lab are:

[edit] Operation

A VNC a client and a server. The server is the program on the machine that shares its screen, and the client (or viewer) is the program that watches and interacts with the server.

The VNC protocol is very simple, based on one graphic primitive: "Put a rectangle of pixel data at a given x, y position". That is, the server sends small rectangles of the framebuffer to the client. This in its simplest form uses a lot of bandwidth, so various methods are used to reduce it. For example, there are various encodings ? methods to determine the most efficient way to transfer these rectangles. The VNC protocol allows the client and server to negotiate which encoding will be used. The simplest encoding, which is supported by all clients and servers, is the raw encoding where pixel data is sent in left-to-right scanline order, and after initial setup, then only transfers rectangles that change. Because of that, this encoding works very well if only a small portion of the screen changes from one frame to the next (like a mouse pointer moving across a desktop, or text being written at the cursor), but bandwidth demands get very high if a lot of pixels change. (Full screen video is the most radical example of this.)

VNC by default uses TCP ports 5900 to 5906, each representing the corresponding x screen (ports 5900 to 5906, for screens :0 to :6). A Java viewer is available in many implementations such as RealVNC on ports 5800 to 5806, following the same pattern. These ports can be changed.

Most Windows computers can only use a single port because Windows lacks the multisession features of UNIX-based servers. The default display number for Windows-based computers is 0 which maps to TCP port 5900.

[edit] Security

By default, VNC is not a secure protocol. While passwords are not sent in plain-text (as in telnet), brute-force cracking could prove successful if both the encryption key and encoded password are sniffed from a network. For this reason it is recommended that a password of at least 8 characters be used. There is also an 8-character limit on some versions of VNC. If a password is sent exceeding 8 characters, the excess characters are removed and the truncated string is compared to the password.

However, VNC may be tunnelled over an SSH or VPN connection which would add an extra security layer with stronger encryption. SSH clients are available for all major platforms (and many smaller platforms as well); SSH tunnels can be created from UNIX clients, Windows clients, Macintosh clients (including Mac OS X and System 7 and up) ? and many others.

UltraVNC supports the use of an open-source encryption plugin which encrypts the entire VNC session including password authentication and data transfer. It also allows authentication to be performed based on NTLM and Active Directory user accounts.

RealVNC offers high-strength encryption as part of its commercial package.

Workspot released AES encryption patches for VNC.

On July 31, 2005, Tridia announced that they were discontinuing development of their free product Tridia VNC and suggested users instead pay for their commercial remote administration software iTvity, claiming that software based on the VNC protocol is unsuitable for deployment in a business environment due to design deficiencies in VNC itself.[1]

[edit] Comparison of VNC software

VNC softwareClientServerRuns on WindowsRuns on Mac OS XRuns on LinuxFLOSSJava viewerEncryptionMultiple Sessions
RealVNC Free [2]YesYesYesNoYesYesYesNo
RealVNC EnterpriseYesYesYesYesYesNoYesYes
TightVNC [3]YesYesYesNoYesYesYesNo
UltraVNC [4]YesYesYesNoNoYesYesYes (plugin)
Chicken of the VNC[5]YesNoNoYesNoYes
Vine Server(OSXvnc) [6]NoYesNoYesNoYes
Apple Remote Desktop[7]YesYesNoYesNoNoYes

[edit] See also

[edit] Further reading

[edit] External links

Wikimedia Commons has media related to:

'Projects > CoVNC' 카테고리의 다른 글

CListBox  (0) 2007.02.21
부요리눅스의 클립보드  (0) 2007.02.20
Virtual Network Computing  (0) 2007.02.14
클립보드의 정의  (0) 2007.02.14
Ultra VNC 소개  (0) 2007.02.13
vnc 소개  (0) 2007.02.09

클립보드의 정의

Projects/CoVNC 2007.02.14 15:59 Posted by soulfree >동네청년<
http://en.wikipedia.org/wiki/Clipboard

Clipboard (software)

From Wikipedia, the free encyclopedia

Jump to: navigation, search
For the writing aid, see Clipboard.

The clipboard is a software program that is used for short-term storage of data as it is transferred between documents or applications, via copy and paste operations. It is most commonly a part of a GUI environment and is usually implemented as an anonymous, temporary block of memory that can be accessed from most or all programs within the environment.

Contents

[hide]

[edit] Basic Clipboard functions

The semantics of the clipboard facility varies from one operating environment to another, and can also vary between versions of the same system. They can sometimes be changed programmatically or by user preference. This can lead to user frustration when switching between environments with different clipboard semantics particularly as copy and paste operations often become embedded in the user's muscle memory.

Most environments support a single clipboard transaction. Each cut or copy overwrites the previous contents. Normally paste operations copy the contents, leaving the contents available in the clipboard for further pasting operations.

[edit] Clipboard data formats

Early implementations of the clipboard stored data as plain text without meta-information such as typeface, type style or color. More recent implemenations support the multiple flavors of data; a flavor is a type of data, allowing complex data structures to be stored. These range from styled text formats such as RTF or HTML, through a variety of bitmap and vector image formats to complex data types like spreadsheets and database entries.

For example cutting a range of cells in a spreadsheet and then pasting them into another sheet may preserve the underlying formulae and data, and may even translate intra-cell references, so that a "SUM(...)" calculation on a sub-range of the cells is converted to refer to the newly pasted copies of those cells.

Not all applications can interpret every flavor that a clipboard supports. Often applications will attempt to translate complex formats into simpler ones they can handle. Many text editors, for example, translate structured data from the clipboard into plain text. This is a common way for users to convert small selections of data into plain text for various purposes.

[edit] Clipboard Management

Modern GUIs often provide a clipboard manager which supports multiple cut and paste transactions. In this model the clipboard is treated as a stack or scrap book, with new cuts and copies being placed added to the top of the list of recent transations. The standard paste operation copies the most recent transaction, while specialized pastes provide access to the other stored transactions. These managers generally also provide a window that displays the transaction history and allows the user to select earlier copies, edit them, change their format and even search amongst them.

Most environments do not save the clipboard contents to any persistent storage - when a user logs out or reboots his or her system the clipboard contents are cleared and forgotten.

[edit] Operating System Specific Clipboards

[edit] Microsoft Windows

In newer versions of the Microsoft Windows operating system, the contents of the clipboard can be viewed at any time by using the ClipBook Viewer application (clipbrd.exe). In older versions of Windows the common practice was to open a copy of the "Notepad" or "Wordpad" editor, and paste into that. Often these operations are available from the "Edit" pull down menu and they may be available via a context menu, usually accessible by context-clicking in the window or dialog entry that is to be cut from or pasted into.

The standard Windows keybindings are:

  • Ctrl-c to copy data onto the clipboard
  • Ctrl-x to cut data to the clipboard
  • Ctrl-v to paste data from the clipboard

Many MS Windows applications also provide Mac OS compatible keybindings.

[edit] Mac OS X

In the Macintosh Operating System the contents can be viewed by selecting the Show Clipboard menu item from the Finder's Edit menu. The standard Mac OS keybindings are:

  • Command-c to copy data into the clipboard
  • Command-x to cut into it
  • Command-v to paste data from the clipboard.

Also available as a secondary, text-only clipboard, is an emacs-style kill-ring. This works in all applications that use standard Cocoa text boxes:

  • Ctrl-k to kill from cursor to end-of-line.
  • Ctrl-y to yank from kill-ring to cursor.

[edit] X Window

In the X Window System (the graphical user interface commonly used on Unix and Linux systems), the clipboard is conventionally used by highlighting text in a window, and using the middle mouse button to paste it into the target. However, there is great diversity among X applications, toolkits and libraries. For example, the GNOME and KDE environments provide closer analogs to the MS Windows clipboard semantics, and applications like Mozilla also provide their own.

[edit] External links

'Projects > CoVNC' 카테고리의 다른 글

부요리눅스의 클립보드  (0) 2007.02.20
Virtual Network Computing  (0) 2007.02.14
클립보드의 정의  (0) 2007.02.14
Ultra VNC 소개  (0) 2007.02.13
vnc 소개  (0) 2007.02.09
Java DataFlavor를 이용한 클립보드 사용  (0) 2007.02.07

Ultra VNC 소개

Projects/CoVNC 2007.02.13 15:29 Posted by soulfree >동네청년<
[리뷰] UltraVNC로 원격 제어를 간편하게!
정상호
06/02/02
1.강력한 원격제어 툴 UltraVNC

원격 제어의 간단한 정의는 멀리 있는 장치를 그곳을 방문하지 않고도 제어 할 수 있다는 정도로 정리할 수 있다. 원격 제어는 다양한 분야에서 널리 사용되고 있으며, PC 분야에서도 이러한 원격 제어를 위한 다양한 소프트웨어가 출시되어 있다.

필자가 이번에 소개할 UltraVNC도 원격 소프트웨어의 일종으로 멀리 떨어져 있는 PC를 간단하고 편리하게 제어할 수 있는 기능을 가지고 있다. VNC란 "Virtual Network Computing"의 약자이며, UltraVNC는 Server 컴퓨터에서 원격 접속한 컴퓨터 모니터로 실시간 캡쳐된 화면을 전송해주는 것은 물론 제어할 수 있는 기능도 제공한다.

이렇게 상대방의 컴퓨터에 접속해 실시간으로 보면서 프로그램들을 제어할 수 있으므로 컴퓨터 엔지니어들이 많이 사용했었고, 최근에는 컴퓨터 A/S 업체에서도 원격 서비스를 하고 있다.

더불어 컴퓨터 관련 업무에 종사하지 않는 일반 사용자라도 한번쯤은 원격 접속의 필요성을 느낄 수 있다. 가령 컴맹인 친구가 프로그램 실행법을 가르쳐 달라고 연락이 왔을 경우나, 인터넷으로 검색할 물건이 있는데 사이트를 제대로 못찾을 경우 등 기타 여러가지 사정이 발생할 수 있다. 이럴 때 직접 가기는 솔직히 너무 귀찮지 않은가? 친구한테 자신의 컴퓨터 실력도 자랑할겸 원격 접속으로 문제를 해결해 준다면 그 친구는 나를 컴신(神)으로 생각할지도 모른다.

참고로 하드웨어에 관심이 있는 사용자라면 WOL(Wake on-LAN)이라는 단어를 본적이 있을 것이다. WOL은 랜을 이용해 컴퓨터를 부팅시키는 기능으로 메인보드/랜/공유기를 이용해 컴퓨터가 꺼져 있어도 외부에서 컴퓨터를 켤 수 있는 기능을 뜻한다. WOL이 가능한 시스템에서 UltraVNC와 같은 원격 제어 프로그램을 사용한다면 더욱 편리할 것이다.

원격 제어 프로그램중에는 시만텍의 PCAnyWhere가 가장 유명하며 널리 사용되고 있고, 윈도우 XP에서도 원격 접속 기능을 지원하지만, UltraVNC는 상용 프로그램이 아니므로 비용을 절감할 수 있는데다가 윈도우 XP 원격 접속 기능보다 뛰어난 기능들을 지원한다.


제품명

UltraVNC v1.0.1

제작사

ultravnc.sourceforge.net

라이센스

프리웨어

다운로드

케이벤치 자료실

주요 특징

  • 리모트 컴퓨터에 접속해 원격 제어 가능
  • 편리한 파일 전송
  • 비디오 드라이버 (UltraWinVNC와 프레임 버퍼 메모리를 바로 연결)
  • MS Logon 지원
  • 뷰어 툴바 및 자바 뷰어 지원
  • 여러 대의 모니터 지원
  • 뷰어에서 보여지는 원격 화면 크기 설정 가능
  • 텍스트 채팅 지원
  • Repeater/Proxy 지원
  • Repeater/SingleClick/Nat to Nat connector 애드온 지원 (애드온은 제작사에서 다운로드 가능)
  • 모든 윈도우 및 Mac OS, 리눅스 지원

2.UltraVNC 설치

원격 제어를 하기 위해서는 우선 제어를 할 컴퓨터와 제어를 당할 리모트 컴퓨터에 각각 UltraVNC가 설치되어 있어야 한다.

설치화면 1

설치화면 2

▲ 설치화면 3 - GNU에 의거해 재배포 및 수정 가능

▲ 설치화면 4

▲ 설치화면 5

UltraVNC에 설치될 컴포넌트를 선택하는 과정이다. UltraVNC는 서버, 뷰어로 작동을 하므로 UltraVNC Server, UltraVNC Viewer에 체크를 해야하고, UltraVNC Mirror Driver는 UltraVNC Server를 선택하면 자동 선택되는 것이니 신경쓰지 않아도 된다. DSM Encryption Plugin은 데이터를 암호화 해주는 플러그인으로 기본 설정이 체크 상태로 되어 있다.

▲ 설치화면 6

Select Additional Tasks에서는 UltraVNC 설치 중 실행하는 옵션을 선택할 수 있다. 아래는 필자가 선택한 옵션들이다.

Register UltraVNC Server as a system service

윈도우 서비스에 UltraVNC를 등록시켜 실행

Start or restart UltraVNC services

윈도우 시작/재시작시 UltraVNC 시작

Configure MS-Logons II

UltraVNC에서 지원하는 MS-Logons II 설정

Clean old VNC registry keys

이전에 설정했던 VNC 레지스트리 항목 삭제

Create UltraVNC desktop icons

데스크탑에 UltraVNC 아이콘 등록

Associate UltraVNC Viewer with the .vnc file extention

확장자가 .vnc인 파일을 UltraVNC 뷰어로 연결

위에 옵션들을 선택했으면 나머지 설치 과정들은 Next 버튼만 클릭하면 된다.

3.UltraVNC 서버 및 Viewer 알아보기

설치를 끝마치면 시작 메뉴와 바탕화면에 UltraVNC Server와 UltraVNC Viewer 아이콘이 등록 됐을 것이다. 그럼 먼저 UltraVNC Server 설정을 해보도록 하자. Server란 이름이 들어간 만큼 이 기능은 원격 제어를 당해야 하는 컴퓨터에서 실행되어야 한다.

UltraVNC Server 설정 화면

Server 설정 화면에서 제공되는 옵션들은 여러 가지 있지만, Incoming connections에서 Port를 지정하고 Authentication에서 비밀번호를 적고 Apply를 클릭해 간단하게 사용할 수도 있다. 이 설정 화면에서 지원하는 옵션들을 순서대로 알아보도록 하자.


Incoming connections

포트 설정 옵션. 기본은 Auto이며, 다른 컴퓨터에서 서버 컴퓨터로 접속할 때 열려있는 포트를 자동으로 찾아 들어오는 것을 말한다. 일반 가정에서 혼자 사용하면 문제가 없지만 회사나 여러 사람이 이용하는 컴퓨터라면 꼭 포트를 적어 보안을 해두는 것이 좋다.
When last client disconnects 보통은 사용자가 원격 제어를 마친 후 아무 것도 안하고 접속을 끊지만, 원격 제어로 서버 관리시 보안적인 이유로 잠그거나 로그오프하길 원할 때 설정한다.
Query on incoming connection

다른 사용자가 접속을 시도할 때 팝업 대화창을 표시해준다.

Keyboard & Mouse

Viewer 및 로컬의 키보드 입력을 중지시킨다.

Multi viewer connections

한 개의 뷰어만 접속할지 여러개의 뷰어를 접속할지 설정한다.

Authentication

VNC 비밀번호를 설정한다. Viewer에서 접속시 이 비밀번호로 접속된다. MS Logon은 유저나 그룹별로 계정을 생성해 레벨을 설정할 수 있다.

File Transfer

파일 전송 허용 (기본적으로 Enable에 체크가 되있으므로 변경할 필요는 없다.)

DSM Plugin

DSM (Data Stream Modification) 플러그인이 설치되어 있다면 사용법을 설정 할 수 있다.

Misc

바탕화면 그림 제거 및 트레이 아이콘 사용안함 등 기타 자잘한 설정을 할 수 있다.

▲ UltraVNC Viewer 설정화면

UltraVNC 뷰어는 서버로 접속해서 접속된 화면을 보여주는 역할을 한다. 여기에서 접속할 서버의 IP와 포트를 적으면 바로 접속이 된다. 퀵 옵션에서는 서버에 접속했을 때 보여질 화면의 최적의 값을 설정할 수 있다. 기본으로 자동으로 검색하도록 선택되어 있으며 서버의 상향 속도가 매우 빠르다면 랜이나 울트라로 설정하고, 느리다면 그 이하의 옵션 중 하나를 선택하면 된다.

▲ UltraVNC Viewer - Connection Options

위 화면은 UltraVNC Viewer에서 Options를 클릭하면 나오는 화면이다. 이 옵션은 Viewer에서 보여지는 디스플레이의 포맷 및 인코딩을 사용자가 직접 설정할 수 있고, 마우스 버튼, 마우스 커서, 툴바 표시, 관람 전용 및 풀 스크린 모드 등의 옵션을 선택할 수 있다. 이제 Server와 Viewer의 옵션들을 알아봤으니 원격 접속을 해서 상대 컴퓨터를 제어 해보도록 하자.

4.원격 제어 하기

원격 제어를 하기전 Server를 담당할 리모트 컴퓨터와 필자의 시스템의 사양 및 인터넷 속도를 비교해보자.



서버

클라이언트

프로세서

intel Pentium 4 3.0GHz

AMD Athlon XP 2500+

메모리

1GB

1GB

그래픽카드

nVIDIA GeForce 5700

ATi RADEON 9550

인터넷 속도

상향 : 73.7KB/s
하향 : 2.7MB/s

상향 : 96.2KB/s
하향 : 1.1MB/s

그럼 리모트 컴퓨터 바탕 화면에 있는 UltraVNC Server를 실행해 포트 설정과 비밀번호를 적고 서버를 실행하도록 하자.

▲ 포트와 비밀번호 입력 (Require MS Logon은 체크하지 않는다)

포트와 비밀번호를 입력한 후 OK를 클릭하면 시스템 트레이에 아이콘이 등록되며 서버가 실행 중임을 알려준다. 이제 필자의 컴퓨터에서 뷰어를 실행하고 서버에 접속하도록 하자.

▲ IP와 포트를 입력 후 Connect 선택

UltraVNC Viewer에서 주의할 점은 제어할 서버가 포트를 가지고 있을 경우 123.123.123.12:8701 처럼 콜론(:)을 입력하고 포트를 입력해야 한다. 포트가 자동으로 선택되어 있다면 그냥 IP만 적어주면 된다. 필자는 우선 Quick Options에서 AUTO로 선택하고 접속을 했다.

▲ 접속 중인 화면

▲ 리모트 컴퓨터에 접속한 화면

서버 컴퓨터에 접속이 되면 그 컴퓨터의 바탕화면이 보인다. 이제 이 바탕화면에 있는 아이콘을 클릭하거나 시작메뉴에 등록되어 있는 프로그램을 선택해 실행하면 된다.

▲ UltraViewer의 툴바

UltraViewer 화면 상단에 위치한 툴바에는 작업을 더욱 편리하게 해주는 기능들이 모여 있어 접속 상태나 풀스크린 전환, 파일 전송,  채팅 기능 등을 편리하게 할 수 있도록 도와준다. 이외에 다른 기능 아이콘들도 제어 작업시 유용하게 사용할 수 있는 것으로 구성되어 있다.

▲ 파일 전송 기능 (작업 종료는 ESC키를 사용)

위 화면은 원격 제어 컴퓨터에서 필자의 컴퓨터로 파일을 전송하는 장면으로 오른쪽이 원격 제어 컴퓨터이며 왼쪽이 필자의 컴퓨터이다. 파일 전송은 윈도우 FTP 클라이언트 사용하듯이 파일 선택 후 Send 나 Receive를 선택하면 된다. 테스트로 73MB 용량의 압축 파일을 원격 제어 컴퓨터에서 필자의 컴퓨터로 전송했을 때의 전송 시간은 25분 정도로 속도는 조금 느렸다.

▲ 리모트 컴퓨터에서 MS 워드를 실행한 화면

프로그램 실행 테스트로는 MS 워드를 실행해봤다. 문서 편집은 비교적 원활하게 사용할 수 있었는데, 원격 제어 컴퓨터에서 필자의 Viewer로 화면을 전송해주는 만큼 약간의 부자연스러운 화면은 감안해야 할 것이다. 또한 원격 제어 컴퓨터에서 한글 입력을 할 때에는 작업 표시줄의 한/영 전환을 이용해야 한다.

▲ 한글 입력시 작업표시줄 한/영 전환 선택

▲ 원격 제어로 다양한 유틸리티도 설치 가능

원격 제어로 다양한 유틸리티를 설치할 수 있는 것은 물론 자유롭게 사용할 수도 있다. 따라서 다운로드에 오랜 시간이 걸리는 작업을 다른 곳에서 받아두고자 할 때 유용하게 사용할 수 있다.

5.프리웨어면서 쉽고 강력한 성능

컴퓨터 초보자들은 다른 사람의 컴퓨터를 원격 제어한다고 하면 무척이나 신기해 한다. 하지만 UltraVNC를 이용해 가정에서 가볍게 사용한다면 리모트 컴퓨터의 IP, 포트, 비밀번호만 입력해 쉽게 제어할 수 있고 별로 어렵지도 않다.

당연한 이야기겠지만 원활한 원격 제어를 하기 위한 전제 조건으로는 리모트 컴퓨터의 인터넷 상향 속도가 매우 중요하다. 필자가 테스트했던 2대의 시스템은 모두 케이블 라인으로 상향 속도가 70~90KB/s 정도여서 리모트 컴퓨터 제어시 약간의 답답함을 느낄 수 있었는데, 빠른 라인을 이용한다면 매우 부드럽게 원격 제어를 할 수 있을 것으로 생각된다. 참고로 UltraVNC Viewer - Quick Options에서 연결 속도 및 화질 등을 수동으로 설정할 수 있었지만 필자가 테스트 한 바로는 자동 설정보다 나은 성능을 보여주지는 못했다.

필자가 이번에 다룬 UltraVNC는 필수 유틸리티도 아니고 널리 쓰일 수 있는 유틸리티는 아니지만 컴퓨터를 사용하는 사용자라면 한번쯤은 겪게 될 원격 제어의 필요성을 대비해 알아두면 좋은 프로그램일 듯 하다.

다만 아쉬운 점이라면 UltraVNC의 기본적인 사용법은 어렵지 않았지만 한글을 지원한다면 보다 깊이 있는 원격 제어 기능들을 이해하는데 도움이 되지 않았을까 생각되지만, 프리웨어에게 무리한 요구를 하는 것만큼 비상식적인 일이 있을까. UltraVNC 1.0.1 버전 이후 더 이상 버전업이 이루어지지 않고 있는데 소스가 공개되어 있는만큼 소스를 개조해 더욱 발전시킨 다른 VNC가 등장하길 기대해 본다.

'Projects > CoVNC' 카테고리의 다른 글

Virtual Network Computing  (0) 2007.02.14
클립보드의 정의  (0) 2007.02.14
Ultra VNC 소개  (0) 2007.02.13
vnc 소개  (0) 2007.02.09
Java DataFlavor를 이용한 클립보드 사용  (0) 2007.02.07
DIB 형식 파일로 저장  (0) 2007.02.06
TAG Ultra VNC

vnc 소개

Projects/CoVNC 2007.02.09 16:12 Posted by soulfree >동네청년<
X윈도우도 원격으로「VNC」

한기철 (마이크로소프트웨어 리뷰어) ( 마이크로소프트웨어 )   2003/07/21
VNC(Virtual Network Computing)는 GNU GPL을 따르는 오픈소스 프로그램이다. VNC는 원격지 서버의 화면을 보여주는(앞서 소개한 프로그램들의 기본 기능에 해당하는) 기능만 제공한다. 이 간결함이 VNC의 매력이다.


VNC를 이용해 원격지 서버에 접속해 불러온 원격지의 데스크톱

TCP/IP 네트워크가 가능한 상황이라면 파일을 주고받는 기능은 FTP 등을 이용할 수 있으며, 채팅은 별도의 채팅 프로그램 등을 이용하면 된다. 카피 앤 페이스트 기능은 자주 사용하지 않을 수 있다. 즉, VNC는 핵심 기능만 간결하게 제공하는 무료 프로그램이다.


VNC의 설정 화면, 그림에 보이는 내용 정도가 설정의 전부라 할 수 있다.

앞에서 살펴본 3개 제품은 원격지 서버를 윈도우만 지원하지만 VNC의 경우는 윈도우, 리눅스, 매킨토시, 솔라리스 등을 지원하므로 리눅스 X윈도우에서 매킨토시 화면을 보거나 윈도우에서 솔라리스의 CDE(Common Desktop Environment)를 볼 수 있다. 이러한 다양한 플랫폼의 원격지 서버를 단일 클라이언트(뷰어)를 통해 접근할 수 있다는 점이 VNC의 가장 큰 장점이라 하겠다.

제품 사양
/
서버 운영체제윈도우 9x/ME/NT4/2000/XP
/
클라이언트 운영체제윈도우 9x8/ME/NT4/2000/XP
/
홈페이지http://www.uk.research.att.com/vnc, http;//www.realvnc.com
/

VNC 뷰어의 경우 자바로 작성된 뷰어를 통해 이들 플랫폼 외에 윈도우 CE 등을 사용하는 모바일 장비 등 직접적으로 지원하는 뷰어가 없는 플랫폼에서도 VNC 서버에 접근할 수 있다. VNC는 RFB라는 프로토콜을 이용해 통신하며 AT&T Labs Cambridge에서 제작되었다. RFB 프로토콜은 내부에 디스플레이 프로토콜과 인풋 프로토콜을 가지고 있는 형태이며, 대부분의 원격제어 솔루션들이 사용하는 프로토콜들도 유사한 형태의 내부 프로토콜의 구분을 가지고 있다. 원격제어 솔루션의 사용보다 이러한 프로그램들의 구현에 관심이 있는 독자라면 VNC 홈페이지에서 개념정립에 도움이 될 문서들도 확인할 수 있을 것이다. 또 하나 참고로 리눅스, 유닉스, 솔라리스용 VNC의 설치와 설정은 터미널 모드에서 이루어지므로 설치 전 반드시 readme 문서를 확인하길 바란다. @

출처 : Tong - firmware님의 갈곳없는것들 ㅠ.ㅠ통

'Projects > CoVNC' 카테고리의 다른 글

클립보드의 정의  (0) 2007.02.14
Ultra VNC 소개  (0) 2007.02.13
vnc 소개  (0) 2007.02.09
Java DataFlavor를 이용한 클립보드 사용  (0) 2007.02.07
DIB 형식 파일로 저장  (0) 2007.02.06
DIB구조  (0) 2007.02.05
TAG VNC

Java DataFlavor를 이용한 클립보드 사용

Projects/CoVNC 2007.02.07 15:00 Posted by soulfree >동네청년<

   // If an image is on the system clipboard, this method returns it;
   // otherwise it returns null.
   public static Image getClipboard() {
       Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
  
       try {
           if (t != null && t.isDataFlavorSupported(DataFlavor.imageFlavor)) {
               Image text = (Image)t.getTransferData(DataFlavor.imageFlavor);
               return text;
           }
       } catch (UnsupportedFlavorException e) {
       } catch (IOException e) {
       }
       return null;
   }

Setting an image on the system clipboard requires a custom Transferable object to hold the image while on the clipboard.
   // This method writes a image to the system clipboard.
   // otherwise it returns null.
   public static void setClipboard(Image image) {
       ImageSelection imgSel = new ImageSelection(image);
       Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null);
   }
  
   // This class is used to hold an image while on the clipboard.
   public static class ImageSelection implements Transferable {
       private Image image;
  
       public ImageSelection(Image image) {
           this.image = image;
       }
  
       // Returns supported flavors
       public DataFlavor[] getTransferDataFlavors() {
           return new DataFlavor[]{DataFlavor.imageFlavor};
       }
  
       // Returns true if flavor is supported
       public boolean isDataFlavorSupported(DataFlavor flavor) {
           return DataFlavor.imageFlavor.equals(flavor);
       }
  
       // Returns image
       public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
           if (!DataFlavor.imageFlavor.equals(flavor)) {
               throw new UnsupportedFlavorException(flavor);
           }
           return image;
       }
   }


'Projects > CoVNC' 카테고리의 다른 글

Ultra VNC 소개  (0) 2007.02.13
vnc 소개  (0) 2007.02.09
Java DataFlavor를 이용한 클립보드 사용  (0) 2007.02.07
DIB 형식 파일로 저장  (0) 2007.02.06
DIB구조  (0) 2007.02.05
DIB를 DDB로 변환  (0) 2007.02.05

DIB 형식 파일로 저장

Projects/CoVNC 2007.02.06 16:39 Posted by soulfree >동네청년<
출처 블로그 > Error 대마왕 ㅋㅋ~ !?!?
원본 http://blog.naver.com/amoros21/140022253596

   CMaptoolDoc* pDoc = GetDocument();


   HANDLE                    hDIB;   

   BITMAPFILEHEADER          bifileHdr;

   BYTE*                     lptrData;

  

   CClientDC dc(this); //클립보드로 현재 이미지를 전송

  

   CDC MemDC;

   MemDC.CreateCompatibleDC(&dc);

  

   CRect rect;

   GetClientRect(rect); //뷰 영역의 크기를 얻어온다   

   rect.right = pDoc->map_arr_x*(pDoc->tile_pixel_x+pDoc->view_size);

   rect.bottom = pDoc->map_arr_y*(pDoc->tile_pixel_y+pDoc->view_size);


   CBitmap BMP;

   BMP.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());

   CBitmap* pOldBitmap = MemDC.SelectObject(&BMP);    // 메모리 DC로 BitMap 선택.

  

   MemDC.BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY);

   // 현재 화면의 내용을 메모리 DC로 전송한다.


   /////////////////////////////////////////////////////////////////////////////////

   // 클립보드에 캡춰한 비트맵을 설정한다.

   OpenClipboard();        // 현재 클립보드를 연다.

   EmptyClipboard();        // 현재 클립보드의 내용을 모두 제거한다.

   SetClipboardData(CF_BITMAP, BMP.GetSafeHandle()); // Capture한 비트맵 설정

   CloseClipboard();


   MemDC.SelectObject(pOldBitmap);

   BMP.Detach();        // 비트맵 객체 제거


   OpenClipboard();


   //클립보드로 카피된게 DIB 형식이 아니면 바로 리턴.

   if(!IsClipboardFormatAvailable(CF_DIB))

   {

       AfxMessageBox("Image file save Fail");

       return;

   }


   hDIB = ::GetClipboardData(CF_DIB);


   if(!hDIB)

   {

       AfxMessageBox("Image file save Fail");

       CloseClipboard();

       return;

   }   


   CloseClipboard();


   //비트맵 헤더의 크기를 계산하고

   bifileHdr.bfType        = 0x4D42;

   bifileHdr.bfSize        = sizeof(BITMAPFILEHEADER) + GlobalSize(hDIB);

   bifileHdr.bfReserved1    = 0;

   bifileHdr.bfReserved2    = 0;

   bifileHdr.bfOffBits        = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

  


   lptrData = (BYTE *)GlobalLock(hDIB);


   char szFilter[] = "BMP File(*.bmp)|*.bmp|All Files(*.*)|*.*||";

   CFileDialog dlg(FALSE, "bmp", "*.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);

   if(IDOK == dlg.DoModal())

   {

       CFile file;

       file.Open(dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite);    

       file.Write(&bifileHdr, sizeof(BITMAPFILEHEADER));

       file.Write(lptrData, GlobalSize(hDIB));

       file.Close();      

   }

   GlobalUnlock(hDIB);

   GlobalFree(hDIB); 

참조사이트

http://www.codeguru.com/Cpp/G-M/bitmap/capturing/article.php/c4919/

http://www.codeguru.com/Cpp/G-M/bitmap/capturing/article.php/c4915/

'Projects > CoVNC' 카테고리의 다른 글

vnc 소개  (0) 2007.02.09
Java DataFlavor를 이용한 클립보드 사용  (0) 2007.02.07
DIB 형식 파일로 저장  (0) 2007.02.06
DIB구조  (0) 2007.02.05
DIB를 DDB로 변환  (0) 2007.02.05
BMP를 DDB로 변환  (0) 2007.02.01
TAG Bitmap, DIB

DIB구조

Projects/CoVNC 2007.02.05 20:54 Posted by soulfree >동네청년<
비트맵 이미지에는 두가지 종류가 있는데 DDB와 DIB가 바로 그것입니다.

DDB(Device Dependent Bitmap)은 이름을 봐도 알수 있드시 장치에 의존하여 비트맵을 출력하는 방식입니다.

DDB는 원래 윈도우 3.0 버전 이하 버전에서 사용하던 포맷인데, DDB는 별도의 팔레트 정보를 파일안에 포함하지 않고 있으므로, 실행 시키는 곳의 장치에 따라 다른 색깔의 이미지가 보여질 수 있습니다. 그에반해 DIB(Device Independent Bitmap) 의 경우 장치에 독립된 비트맵이기 때문에 어떤 장치에서 실행을 시키더라도 같은 모습의 비트맵 이미지를 볼수 있습니다.

물론 DIB의 중요도가 훨씬 더 높고 우리가 이번 시간에 알아볼 비트맵 포맷도 DIB 이지만, DDB 역시도 아직까지 많이 사용되고 있으므로 무시해도 되는 개념은 아님을 알아두시길 바랍니다.

DDB는 비트맵 이미지에 대한 간단한 정보와 이미지 비트만으로 구성되어져 있기때문에 아주 간단하게 구성되어 있지만, DIB는 꽤나 복잡한 구조로 이루어져 있습니다.


이런식으로 구성되어져 있는데, 이제 하나하나 그 멤버들을 살펴보도록 하겠습니다.

BITMAPFILEHEADER

typedef struct tagBITMAPFILEHEADER
{
   WORD    bfType;
   DWORD  bfsize;
   WORD    bfReserved1;
   WORD    bfReserved2;
   DWORD  bfOffBits;
} BITMAPFILEHEADER;

bfType Bitmap 파일의 형식이 기록되는 부분입니다.
비트맵 파일은 반드시 bfType의 값이 BM(0x42, 0x4d)이어야 합니다.
bfSize비트맵 파일의 크기를 바이트 단위로 나타냅니다.
bfReserved1  항상 0으로 설정해주면 됩니다. 현재 사용되지 않는 비트입니다.
bfReserved2마찬가지로 0으로 설정해주시면 됩니다.
bfOffBits이 값은 BITMAPFILEHEADER, BITMAPINFOHEADER, RGBQUAD
3개 구조체의 크기를 더한 값으로 실제 이미지 비트의 OffSet을 의미합니다.

BITMAPFILEHEADER은 구조체명에서도 알수 있듯이, 비트맵 이미지 그 자체에 대한 정보보다는, 비트맵 파일에 대한 정보를 주로 가지고 있습니다. 따라서 비트맵 파일을 DIB 형식으로 저장할 때에만 쓰이고, 화면에 출력할때에는 쓰이지 않는 구조체입니다.

BITMAPINFOHEADER

typedef struct tagBITMAPINFOHEADER
{
   DWORD biSize;
   LONG biWidth;
   LONG biHeight;
   WORD biPlanes;
   WORD biBitCount;
   DWORD biCompression;
   DWORD biSizeImage;
   LONG biXPelsPerMeter;
   LONG biYPelsPerMeter;
   DWORD biClrUsed;
   DWORD biClrImportant;
} BITMAPINFOHEADER;

biSize 이 구조체의 크기를 나타냅니다.
biWidth비트맵의 가로 픽셀수.
biHeight비트맵의 세로 픽셀수.
이 값이 양수이면, 바텀업 방식이라고 하며, 출력시, 아래쪽 부터 출력을 해야 합니다.
또 이 값이 음수이면, 탑다운 방식이라고 하며, 출력시, 위쪽부터 차례로 출력 합니다.
biPlanes비트맵의 플래인 개수를 나타내는데 이 값은 반드시 1로 고정되어야 합니다.
biBitCount한 픽셀이 몇개의 비트로 이루어지는가를 나타내며 이 값에 따라 픽샐이 가질수 있는 색상수가 결정됩니다.
1이면 흑백, 4이면 16색, 8이면 256색... 과 같이, 2의 제곱승으로 계산됩니다.
biCompression압축 방식을 나타내는데요. 반드시 바텀업 방식일때만 압축이 가능하며,
이 값이 BI_RGB이면 압축되지 않았다는 것을 의미하고,
BI_RLE8이면 8비트 압축, BI_RLE4이면 4비트 압축으로 압축되어 있는 것입니다.
biSizeImage이미지의 크기를 바이트 단위로 나타내며 BI_RGB(압축이 안된 상태) 비트맵에서의 이 값은 0입니다.
biXPelsPerMeter가로 해상도를 의미합니다.
biYPelsPerMeter세로 해상도를 의미합니다.
biClrUsed비트맵에 사용된 색상수를 의미하며, 이값에 따라 RGBQUAD의 배열을 메모리 할당하여서 읽어오시면 됩니다.
이 값이 0이면 모든 색깔을 다 사용한다는 의미입니다.
biClrImportant 비트맵을 출력하는데 필수적인 색상수를 나타내며, 이 값이 0이면 모든 색상을 다 사용한다는 의미입니다.

이 구조체에는 이미지의 폭, 높이, 해상도, 팔레트 정보등 비트맵의 실제 구성 정보가 기록 되어져 있습니다.

RGBQUAD는 팔레트를 사용하는 경우에만 사용되며 팔레트를 쓰지 않는 경우에는 사이즈가 0입니다. 우리는 팔레트를 사용하지 않으므로, RGBQUAD에 대한 내용은 언급하지 않고 넘어가도록 하겠습니다.

'Projects > CoVNC' 카테고리의 다른 글

Java DataFlavor를 이용한 클립보드 사용  (0) 2007.02.07
DIB 형식 파일로 저장  (0) 2007.02.06
DIB구조  (0) 2007.02.05
DIB를 DDB로 변환  (0) 2007.02.05
BMP를 DDB로 변환  (0) 2007.02.01
비트맵 파일 저장하고 읽기  (0) 2007.02.01
TAG Bitmap, bmp, DDB, DIB

DIB를 DDB로 변환

Projects/CoVNC 2007.02.05 17:14 Posted by soulfree >동네청년<


출처 네이버 블로그 > 탑건매직
http://blog.naver.com/topgunmagic/120033732401


ReadDIB.zip

* DIB

1. 직접 비트맵을 파싱하여 처리

2.  DIB를 DDB 로 변환 (2가지)

[코드]

case WM_PAINT:
  hdc=BeginPaint(hWnd, &ps);

  // 1) loadimage를 이용한 변환  (DDB->DIB)  ----1
  hbit = (HBITMAP) LoadImage( NULL, "dragon00.bmp",
     IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );

  MemDC=CreateCompatibleDC(hdc);
  SelectObject(MemDC,hbit);

  BitBlt(hdc,0,0,96,96,MemDC,0,0,SRCCOPY);
 
 
 
  // DDB로 변환하여 그리기 ---------------------2
/* hbit=CreateDIBitmap(hdc,(BITMAPINFOHEADER *)ih,
     CBM_INIT, (PBYTE)fh+fh->bfOffBits,
     (BITMAPINFO)ih,DIB_RGB_COLORS);   

       MemDC=CreateCompatibleDC(hdc);
  SelectObject(MemDC,hbit);

  BitBlt(hdc,0,0,ih->biWidth,ih->biHeight,MemDC,0,0,SRCCOPY);
*/

  // DIB로 그리기  -----------------------------3
  if (fh) {
  SetDIBitsToDevice(hdc,0,0,bx,by,0,0,0,by,pRaster,(BITMAPINFO *)ih,DIB_RGB_COLORS);
  //StretchDIBits(hdc,0,0,bx*2,by*2,0,0,bx,by,pRaster,(BITMAPINFO *)ih,DIB_RGB_COLORS,SRCCOPY);
  }
  EndPaint(hWnd, &ps);
  return 0;



// 비트맵 파싱

BITMAPFILEHEADER *fh=NULL;
BITMAPINFOHEADER *ih;
BITMAPINFO* info;
int bx,by;
BYTE *pRaster;


// DDB 변환용
HBITMAP hbit;



void LoadDIB(char *Path)
{
HANDLE hFile;
DWORD FileSize, dwRead;

hFile=CreateFile(Path,GENERIC_READ,0,NULL,
  OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile==INVALID_HANDLE_VALUE) {
  return;
}

FileSize=GetFileSize(hFile,NULL);

if (fh)
  free(fh);


// 헤더 정보 읽기
fh=(BITMAPFILEHEADER *)malloc(FileSize);
ReadFile(hFile,fh,FileSize,&dwRead,NULL);
CloseHandle(hFile);


  // 데이타의 위치
pRaster=(PBYTE)fh+fh->bfOffBits;
// 비트맵 info header
ih=(BITMAPINFOHEADER *)((PBYTE)fh+sizeof(BITMAPFILEHEADER));


  // info
/*info->bmiHeader = ih;
info->bmiColors = (RGBQUAD)((PBYTE)fh+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));*/



bx=ih->biWidth;
by=ih->biHeight;

  }




'Projects > CoVNC' 카테고리의 다른 글

DIB 형식 파일로 저장  (0) 2007.02.06
DIB구조  (0) 2007.02.05
DIB를 DDB로 변환  (0) 2007.02.05
BMP를 DDB로 변환  (0) 2007.02.01
비트맵 파일 저장하고 읽기  (0) 2007.02.01
CF_BITMAP 사용하기  (0) 2007.01.30
TAG DDB, DIB, 비트맵

BMP를 DDB로 변환

Projects/CoVNC 2007.02.01 14:03 Posted by soulfree >동네청년<

출처 : 블로그 > Priss In The Attic
http://blog.naver.com/priling/80012774193
===========================================

[부대에서 구린 컴퓨터로나마 비주얼C를 돌려볼 수 있다는 것이 얼마나 고마운지 모릅니다.

2년이나 쉬어서 그런지 코드 한 줄 쓰기도 낯설더군요.

그래도 옛 생각 새록새록 나는게 기분이 삼삼~하네요

무려 3일 동안이나 삽질하던거를 잊어버리지 않도록 그냥 한번 써봤습니다.]



BMP 파일은 DIB이다. 윈도우즈 프로그램에서 이것을 이용하기 위해서는 내부적으로 DDB로 바꾸어 주는 편이 낫다. DIB의 형식을 유지한 채로 메모리 상에서 이용하는 방법이 없는 것은 아니지만 (CreateDIBSection함수) 이렇게 되면 당연히 이미지 처리 속도가 늦어지게 된다.
DIB라는 것이 화면의 DC와는 별개로 자체적인 컬러 포맷을 가진 이미지 형식이므로 이것을 DC에서 출력하기 위해선 DDB로 변환해 DC와 같은 포맷으로 만들어 주어야만 원만한 처리 속도를 기대할 수 있다.

1. BMP 파일을 어떻게 화면에 뿌릴까?
도스 시절 때처럼 생각하면 헤맨다. 도스 때에 그냥 메모리에 그림 파일을 읽어 올려서 화면 컬러 포맷에 맞추어서 이미지 데이터를 비디오 메모리에 전송하면 되었지만, 윈도우는 DC라는 시스템이 있어서 조금 거쳐가야 한다.

즉 읽어들인 그림 파일을 프로그래머 임의의 방식으로 가지고 있다가 화면에 뿌려주는 게 아니고 DC에 보관했다가 DC간의 메모리 전송으로 화면에 출력해야 한다는 것이다.

CreateCompatibleDC 함수를 사용해 메모리 상에 화면 DC와 같은 포맷의 DC를 만든다. 이것을 memDC라고 하면, memDC에서 SelectObject 함수를 사용해 HBITMAP 형식의 이미지를 붙일 수 있다. (이것은 DC에서 브러시나 펜 등을 설정하는 것과 같다. 한번에 하나의 비트맵이 선택될 수 있다.)

이제 우리는 두개의 DC를 가지고 있다.
주화면 DC (hDC라고 하자)와 memDC..
두 개의 DC끼리는 BitBlt 함수를 사용해 이미지를 복사할 수 있다.


2. 그럼 BMP 파일을 DDB로 바꾸는 방법은?
SelectObject 함수로 이미지를 DC에 선택하려면 DDB가 필요하다. 그러나 BMP 파일은 DIB이기 때문에 변환이 필요하다. 다음 함수가 바로 DIB를 DDB로 한방에 바꾸어 주는 놈이다.

HBITMAP CreateDIBitmap(
  HDC hdc,                        // handle to DC
  CONST BITMAPINFOHEADER *lpbmih, // bitmap data
  DWORD fdwInit,                  // initialization option
  CONST VOID *lpbInit,            // initialization data
  CONST BITMAPINFO *lpbmi,        // color-format data
  UINT fuUsage                    // color-data usage
);

인자 설명 ::
HDC hdc  => 생성될 DDB의 컬러 포맷을 참조할 DC (주화면 DC 핸들을 넣으면 된다)
CONST BITMAPINFOHEADER *lpbmih  => 말그대로 BMP파일의 BITMAPINFOHEADER
DWORD fdwInit  => CBM_INIT라는 상수를 넣으면 된다 (자세한 건 msdn참조)
CONST VOID *lpbInit  => 이미지 데이터 블록의 포인터를 넣어주자
CONST BITMAPINFO *lpbmi  => BMP 파일의 BITMAPINFO의 포인터를 넘기면 된다
UINT fuUsage  => 디스플레이의 현재 색비트 수가 8이하라면 DIB_PAL_COLORS, 16이상이면 DIB_RGB_COLORS 이다


3. 그외 겪었던 잡다한 문제들
(1) 색깔이 이상하게 나온다?
처음에 겪은 버그. 이미지의 모양은 제대로 출력 되지만 색깔이 이상했다.
RGB의 순서가 뒤바뀐 듯한 느낌. 실제로
빨강이 초록으로
초록이 파랑으로
파랑이 빨강으로 표시되는 현상이 생겼다.

이것은 작은 실수에 의한 것이다. 그러나 찾기는 쉽지 않다. 게다가 이미지의 모양은 제대로 출력되면서 색깔만이 이상하게 나오기 때문에 속기 쉬워서 컬러 포맷의 비트 변환에서 계속 문제를 찾느라 시간을 허비했다. 이 버그는 이미지의 왼쪽 세로 라인 하나가 오른쪽에 잘려붙여져 나타나는 현상을 동반한다.
이건 다름아니라.. 이미지 데이터 블록의 포인터를 잘못 잡은 탓이다.
BMP파일에서 이미지 데이터 블록을 읽어들일 때 한 바이트라도 빗나가면 RGB의 순서가 뒤바뀌게 되는 것이다. BMP 파일에서 헤더부터 순차적으로 읽어들이다가 조금이라도 어긋나면 이렇게 되버린다. 차라리 나은 방법은 fseek를 사용해서 BMP파일의 뒤에서 위치를 재어 들어가는 것이다.

// bmi는 BITMAPINFO 구조체, pixels는 이미지 데이터를 보관할 포인터
fseek(fp, -(int)(bmi->bmiHeader.biSizeImage), SEEK_END);
pixels = (unsigned char*) malloc(bmi->bmiHeader.biSizeImage);
fread(pixels, bmi->bmiHeader.biSizeImage, 1, fp);


(2) 8비트 BMP를 읽어들일 때 팔레트 문제
8비트라고 해서 별다른 게 있는 것은 아니다. CreateDIBitmap 함수는 컬러 포맷에 관계없이 대상 DC와 BITMAPINFO 구조체 정보를 이용해 양쪽을 잘 매치해준다.
다만, 8비트는 팔레트를 파일에서 읽어줘야 한다는 문제가 있다.
어려움을 겪은 부분은 BIMAPINFO 구조체의 팔레트 부분이었다.

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;

두번째 멤버변수가 바로 팔레트를 위한 부분인데, 문제는 배열의 크기가 1이라는 것이다.
8비트 팔레트는 256개의 RGBQUAD가 필요한데 배열을 확보하기 위해서 약간의 꽁수가 필요하다.

BITMAPINFO* bmi=NULL;
bmi = (BITMAPINFO*) malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);

fread(bmi, sizeof(BITMAPINFOHEADER), 1, fp);
if (bmi->bmiHeader.biBitCount == 8)
fread(bmi->bmiColors, sizeof(RGBQUAD), 256, fp);

그냥 변수로 선언하면 팔레트엔 1개의 엔트리 뿐이게 되므로 포인터 선언을 한 후 메모리 할당을 해주는데 이때 255개의 RGBQUAD 분량의 메모리를 더 잡아주면 이미 BITMAPINFO에 들어 있는 1개의 엔트리에 255개 만큼의 엔트리가 더해지게 된다.
그 후에 BITMAPINFOHEADER를 읽어들이면 다음은 팔레트 차례가 된다.




// BMP 읽어서 화면에 뿌려주는 코드의 핵심부
HBITMAP hbm;
:
:
BMPLoad("a.bmp");
hdc = GetDC(hWnd);
hbm = CreateDIBitmap(hdc, &(bmi->bmiHeader), CBM_INIT, pixels, bmi, DIB_RGB_COLORS);
memDC = CreateCompatibleDC(hdc);
SelectObject(memDC, hbm);
BitBlt(hdc, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, memDC, 0, 0, SRCCOPY);
ReleaseDC(hWnd,hdc);   




// BMP 로드 함수
BITMAPFILEHEADER bf;
BITMAPINFO* bmi=NULL;
unsigned char* pixels=0;
:
:
int BMPLoad(char* filename)
{

FILE* fp;
fp = fopen(filename, "rb");

bmi = (BITMAPINFO*) malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255);

fread(&bf, sizeof(BITMAPFILEHEADER), 1, fp);
fread(bmi, sizeof(BITMAPINFOHEADER), 1, fp);
if (bmi->bmiHeader.biBitCount == 8)
{
  fread(bmi->bmiColors, sizeof(RGBQUAD), 256, fp);
}

       // 픽셀 데이터 읽기
fseek(fp, -(int)(bmi->bmiHeader.biSizeImage), SEEK_END);
pixels = (unsigned char*) malloc(bmi->bmiHeader.biSizeImage);
fread(pixels, bmi->bmiHeader.biSizeImage, 1, fp);

fclose(fp);


return TRUE;
}


색깔 바뀌는 버그는 군대 오기 전에도 DDRAW 만지면서 한 번 당해서 고생했던 기억이 난다.
문제는 다 해결하고 나서야 어? 전에도 이랬던 적이 있었던거 같애! 거 희한하네~ 하는게 문제지.

'Projects > CoVNC' 카테고리의 다른 글

DIB구조  (0) 2007.02.05
DIB를 DDB로 변환  (0) 2007.02.05
BMP를 DDB로 변환  (0) 2007.02.01
비트맵 파일 저장하고 읽기  (0) 2007.02.01
CF_BITMAP 사용하기  (0) 2007.01.30
클립보드에서 이미지 읽기  (0) 2007.01.25
TAG bmp, DDB, DIB

비트맵 파일 저장하고 읽기

Projects/CoVNC 2007.02.01 00:08 Posted by soulfree >동네청년<

BMP파일 읽고 저장하는 소스인데요 고수님 봐주세요

struct userheader {

      unsigned count;           // <--여기 count 에다가는 0을 넣고 싶고요

      char maker[4];            // <--name <---요걸 넣고 싶어요

} User_Header;


위 구조체를 아래 소스에있는

FILE_HEADER 앞전에 넣어줄려고 합니다.


// include header file
//------------------------------------------------------------------------------------
#include <stdio.h>
#include <memory.h>


//------------------------------------------------------------------------------------
// 상수값 정의
//------------------------------------------------------------------------------------
#define READ_FILE_NAME "test.bmp" // 비트맵 파일 이름 정의
#define WRITE_FILE_NAME "test_writed.bmp" // 비트맵 파일 이름 정의


//------------------------------------------------------------------------------------
// Bitmap File Header 에 대한 구조체 정의
//------------------------------------------------------------------------------------

// 32bit 컴퓨터로 인한 패딩 현상 방지를 위해
#pragma pack(push, 1)

typedef struct tFILE_HEADER
{
unsigned short bfType;
unsigned long bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned long bfOffBits;
} FILE_HEADER;

#pragma pack(pop)


//------------------------------------------------------------------------------------
// Bitmap Info Header 에 대한 구조체 정의
//------------------------------------------------------------------------------------

typedef struct tINFO_HEADER
{
   unsigned long biSize;
   unsigned long biWidth;
   unsigned long biHeight;
   unsigned short biPlanes;
   unsigned short biBitCount;
   unsigned long biCompression;
   unsigned long biSizeImage;
   unsigned long biXPelsPerMeter;
   unsigned long biYPelsPerMeter;
   unsigned long biClrUsed;
   unsigned long biClrImportant;
} INFO_HEADER;

//------------------------------------------------------------------------------------
// 비트맵 파일 전체에 대한 구조체 정의
//------------------------------------------------------------------------------------

typedef struct tMY_BITMAP
{
FILE_HEADER  bmpFileHeader; // file header 부분
INFO_HEADER  bmpInfoHeader; // info header 부분
unsigned char* bmpPalette;  // palette 부분
unsigned char* bmpRawData;  // 실제 이미지 data 부분
} MY_BITMAP;


//------------------------------------------------------------------------------------
// 함수 원형 정의부
//------------------------------------------------------------------------------------

int get_bmpFileHeader(unsigned char* bmpBuf, MY_BITMAP* pBitmap);
int get_bmpInfoHeader(unsigned char* bmpBuf, MY_BITMAP* pBitmap);
int get_bmpPalette(unsigned char* bmpBuf, MY_BITMAP* pBitmap);
int get_bmpRawData(unsigned char* bmpBuf, MY_BITMAP* pBitmap);
int write_bmpInfo(MY_BITMAP* pBitmap);
int make_bmp(unsigned char* bmpBuf, MY_BITMAP* pBitmap);

//------------------------------------------------------------------------------------
// main 함수 시작
//------------------------------------------------------------------------------------

int main(int argc, char *argv[])
{
MY_BITMAP Bitmap;   // 비트맵 데이터가 저장될 구조체 선언
FILE *pBitmapFile;   // 파일을 읽기 위한 스트림
unsigned int nFileSize;  // 파일의 사이즈
unsigned char* pBitmapBuf; // 파일의 모든 데이타가 저장될 버퍼
int is;      // 함수 호출이 성공했는지 보기위한 변수


pBitmapFile = fopen(READ_FILE_NAME, "rb"); // 비트맵 파일을 연다.

// 파일이 존재하지않는 등의 이유로 파일 열기를 실패 하였을경우 pBitmapFile값은 null
if (!pBitmapFile)
{
  printf("failed to open bitmap file...\nExit...\n");
  return 0; // 프로그램 종료
}

// 파일의 사이즈를 알아오기 위해 파일 포인터의 위치를 가장 끝으로 옮기후 그 위치를 읽어온다.
// 파일의 사이즈를 알아야 그만큼의 바이트를 메모리에 할당하고 파일의 모든 데이터를
// 변수값에 저장할 수 있다.
fseek(pBitmapFile, 0L, SEEK_END); // 파일 포인터의 위치를 끝으로 옮기기
nFileSize = ftell(pBitmapFile);  // 현재 파일 포인터의 위치를 읽어오기


// 파일의 사이즈 만큼 바이트 수를 메모리에 할당한다
pBitmapBuf = new unsigned char[nFileSize];


// 파일의 데이터를 읽어오기 위해 다시 파일 포인터의 위치를 처음으로 옮긴다
fseek(pBitmapFile, 0L, SEEK_SET);

// 파일의 데이터를 처음부터 파일의 사이즈만큼 바이트단위로 읽는다.
fread(pBitmapBuf, sizeof(char), nFileSize, pBitmapFile);
printf("read bitmap file...\n");

// 이제 파일의 모든 데이터는 pBitmapBuf에 저장되어 있다
fclose(pBitmapFile); // 파일 닫기



// pBitmapBuf 에서 Bitmap File Header 부분을 분리해 낸다
is = get_bmpFileHeader(pBitmapBuf, &Bitmap);
if (!is) // 실패시 프로그램 종료
{
  printf("failed to read bitmap file header...\n\n");
}
printf("get bitmap file header...\n");

// pBitmapBuf 에서 Bitmap Info Header 부분을 분리해 낸다
is = get_bmpInfoHeader(pBitmapBuf, &Bitmap);
if (!is) // 실패시 프로그램 종료
{
  printf("failed to read bitmap info header...\n\n");
}
printf("get bitmap info header...\n");

// pBitmapBuf 에서 Bitmap Palette 부분을 분리해 낸다
is = get_bmpPalette(pBitmapBuf, &Bitmap);
if (!is) // 실패시 프로그램 종료
{
  printf("failed to read bitmap palette...\n\n");
}
printf("get bitmap palette...\n");

// pBitmapBuf 에서 Bitmap Raw Data 부분을 분리해 낸다
is = get_bmpRawData(pBitmapBuf, &Bitmap);
if (!is) // 실패시 프로그램 종료
{
  printf("failed to read bitmap raw data...\n\n");
}
printf("get bitmap raw data...\n");


// 비트맵 정보 출력
write_bmpInfo(&Bitmap);
printf("write bitmap info...\n");

if (pBitmapBuf) // 버퍼 메모리 해제
{
  delete pBitmapBuf;
  pBitmapBuf = NULL;
}

// 구조체의 내용을 기반으로 파일에 쓰기 위해 임시 버퍼를 만듬
// 당연히 버퍼의 크기는 파일의 크기만큼 이어야 함
nFileSize = Bitmap.bmpFileHeader.bfSize;

pBitmapBuf = new unsigned char[nFileSize];

// 임시 버퍼에 구조체의 내용을 채운다
is = make_bmp(pBitmapBuf, &Bitmap);
if (!is) // 실패시 프로그램 종료
{
  printf("failed to make bitmap...\n\n");
}

// 파일에 써서 test_writed.bmp 파일을 만들어낸다
pBitmapFile = fopen(WRITE_FILE_NAME, "wb");
fwrite(pBitmapBuf, sizeof(char), nFileSize, pBitmapFile);
printf("make bitmap file...\n");
fclose(pBitmapFile);

// 지금까지 쓰였던 메모리 해제
if (pBitmapBuf)
{
  delete pBitmapBuf;
  pBitmapBuf = NULL;
}

if (Bitmap.bmpPalette) delete Bitmap.bmpPalette;
if (Bitmap.bmpRawData) delete Bitmap.bmpRawData;


return 0;
}

//------------------------------------------------------------------------------------
// 버퍼에서 file header 부분을 읽어와 구조체에 저장
//------------------------------------------------------------------------------------

int get_bmpFileHeader(unsigned char* bmpBuf, MY_BITMAP* pBitmap)
{
unsigned int len = sizeof(FILE_HEADER);

if (!bmpBuf || !pBitmap) return 0;

// bmpBuf 에서부터 len 만큼을 구조체의 bmpfileHeader 에 memory copy
memcpy(&pBitmap->bmpFileHeader, bmpBuf, len);

return 1;
}

//------------------------------------------------------------------------------------
// 버퍼에서 info header 부분을 읽어와 구조체에 저장
//------------------------------------------------------------------------------------

int get_bmpInfoHeader(unsigned char* bmpBuf, MY_BITMAP* pBitmap)
{
unsigned int len = sizeof(INFO_HEADER);
unsigned int start = sizeof(FILE_HEADER);

if (!bmpBuf || !pBitmap) return 0;

// bmpBuf 에서부터 len 만큼을 구조체의 bmpInfoHeader 에 memory copy
memcpy(&pBitmap->bmpInfoHeader, bmpBuf + start, len);

return 1;
}

//------------------------------------------------------------------------------------
// 버퍼에서 palette 부분을 읽어와 구조체에 저장
//------------------------------------------------------------------------------------

int get_bmpPalette(unsigned char* bmpBuf, MY_BITMAP* pBitmap)
{
unsigned int nPaletteEntry;
unsigned int start = sizeof(FILE_HEADER) + sizeof(INFO_HEADER);
unsigned int len;

// 몇 비트 비트맵인지
switch (pBitmap->bmpInfoHeader.biBitCount)
{
  case 24: // true 칼라
  nPaletteEntry = 0;
  break;
  case 8:  // 256 칼라
  nPaletteEntry = 256;
  break;
  case 4:  // 16 칼라
  nPaletteEntry = 16;
  break;
  case 1:  // 2 칼라
  nPaletteEntry = 2;
  break;
  default:
  return 0;
}

// true 칼라면 팔레트를 사용하지 않는다
if (nPaletteEntry == 0)
{
  pBitmap->bmpPalette = NULL;
  return 1;
}
else
{
  // 메모리 할당
  pBitmap->bmpPalette = new unsigned char[nPaletteEntry * 3];


  len = nPaletteEntry * 3;
  memcpy(pBitmap->bmpPalette, bmpBuf + start, len); // 메모리 카피
}

return 1;
}

//------------------------------------------------------------------------------------
// 버퍼에서 raw data 부분을 읽어와 구조체에 저장
//------------------------------------------------------------------------------------

int get_bmpRawData(unsigned char* bmpBuf, MY_BITMAP* pBitmap)
{
unsigned int len;
unsigned int start = pBitmap->bmpFileHeader.bfOffBits;

//읽어올 크기 정하기
len = pBitmap->bmpFileHeader.bfSize - start;


// 읽어올 크기만큼 메모리 할당
pBitmap->bmpRawData = new unsigned char[len];

// 메모리 카피
memcpy(pBitmap->bmpRawData, bmpBuf + start, len);

return 1;
}

//------------------------------------------------------------------------------------
// 구조체의 내용을 화면에 출력
//------------------------------------------------------------------------------------

int write_bmpInfo(MY_BITMAP* pBitmap)
{
printf("\n");
printf("   bftype : %c%c\n", pBitmap->bmpFileHeader.bfType & 0x00ff,  pBitmap->bmpFileHeader.bfType >> 8);
printf("     Size : %d [Byte]\n", pBitmap->bmpFileHeader.bfSize);
printf("    Width : %d\n", pBitmap->bmpInfoHeader.biWidth);
printf("   Height : %d\n", pBitmap->bmpInfoHeader.biHeight);
printf("Bit Count : %d\n", pBitmap->bmpInfoHeader.biBitCount);
printf("Image Data:");

for (int i = 0; i < 200; i++)
{
  if (i % 20 == 0) printf("\n");
  printf("%2x ", pBitmap->bmpRawData[i]);
}
printf("\n...............\n");

return 1;
}

//------------------------------------------------------------------------------------
// 구조체의 내용을 bmpBuf 에 하나로 묶음
// 파일에 쓰는거는 메인함수에 있습니다.
//------------------------------------------------------------------------------------

int make_bmp(unsigned char* bmpBuf, MY_BITMAP* pBitmap)
{
unsigned int nSize = pBitmap->bmpFileHeader.bfSize;
unsigned int len, start;

// file header
start = 0;
len = sizeof(FILE_HEADER);
memcpy(bmpBuf + start, &pBitmap->bmpFileHeader, len);

// info header
start += len;
len = sizeof(INFO_HEADER);
memcpy(bmpBuf + start, &pBitmap->bmpInfoHeader, len);

// 팔렛트가 존재하면 팔렛트의 내용도 써주어야 한다
if (pBitmap->bmpPalette != NULL)
{
  start += len;
  len = pBitmap->bmpFileHeader.bfOffBits - start;
  memcpy(bmpBuf + start, pBitmap->bmpPalette, len);
}

// raw data
start += len;
len = nSize - start;
memcpy(bmpBuf + start, pBitmap->bmpRawData, len);

return 1;
}


'Projects > CoVNC' 카테고리의 다른 글

DIB를 DDB로 변환  (0) 2007.02.05
BMP를 DDB로 변환  (0) 2007.02.01
비트맵 파일 저장하고 읽기  (0) 2007.02.01
CF_BITMAP 사용하기  (0) 2007.01.30
클립보드에서 이미지 읽기  (0) 2007.01.25
Swap16IfLE() 매크로  (0) 2007.01.24
TAG 비트맵

CF_BITMAP 사용하기

Projects/CoVNC 2007.01.30 20:46 Posted by soulfree >동네청년<
 // to set a bitmap to a button, load a 32x32 bitmap
   // and copy it to clipboard. Call CommandBarButton's PasteFace()
   // to copy the bitmap to the button face. to use
   // Outlook's set of predefined bitmap, set button's FaceId to     //the
   // button whose bitmap you want to use
   HBITMAP hBmp =(HBITMAP)::LoadImage(_Module.GetResourceInstance(),
   MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);

   // put bitmap into Clipboard
   ::OpenClipboard(NULL);
   ::EmptyClipboard();
   ::SetClipboardData(CF_BITMAP, (HANDLE)hBmp);
   ::CloseClipboard();
   ::DeleteObject(hBmp);       
   // set style before setting bitmap
   spCmdButton->PutStyle(Office::msoButtonIconAndCaption);

'Projects > CoVNC' 카테고리의 다른 글

BMP를 DDB로 변환  (0) 2007.02.01
비트맵 파일 저장하고 읽기  (0) 2007.02.01
CF_BITMAP 사용하기  (0) 2007.01.30
클립보드에서 이미지 읽기  (0) 2007.01.25
Swap16IfLE() 매크로  (0) 2007.01.24
자바 이미지 저장  (0) 2007.01.24

클립보드에서 이미지 읽기

Projects/CoVNC 2007.01.25 04:17 Posted by soulfree >동네청년<
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
char Mes[]="왼쪽 버튼을 비트맵 복사, 오른쪽 버튼은 비트맵 붙이기";
HBITMAP hBit,hOldBitmap;
HDC hmemDC;
BITMAP bmp; //비트맵 구조체 DDB형식

switch(message)
{
case WM_CREATE:
if(OpenClipboard(hWnd))
{
EmptyClipboard();
CloseClipboard();
}
return 0;
case WM_LBUTTONDOWN:
//리소스타입인 DIB를 DDB형식으로 변환함
hBit=LoadBitmap(g_hInst,MAKEINTRESOURCE(IDB_BITMAP1));
if(OpenClipboard(hWnd))
{
EmptyClipboard();
SetClipboardData(CF_BITMAP,hBit);
CloseClipboard();
}
return 0;
case WM_RBUTTONDOWN:
//클립보드상에 들어있는지 없는지 여부
if(!IsClipboardFormatAvailable(CF_BITMAP))
return 0;
if(OpenClipboard(hWnd))
{
hBit=(HBITMAP)GetClipboardData(CF_BITMAP);
CloseClipboard();
hdc=GetDC(hWnd);
//화면DC 핸들을 주면 동일한 특성을 지닌 DC를 메모리에 만들고 핸들을 리턴
hmemDC=CreateCompatibleDC(hdc);
//클립보드에 얻은 비트맵을 메모리DC에 선택하고 HBITMAP캐스팅(원래 HGDIOBJ)
hOldBitmap=(HBITMAP)SelectObject(hmemDC,hBit);
//조사하고자 하는 핸들이 첫번째 인수 비트맵의 폭, 높이, 색상 정보만 조사됨
GetObject(hBit,sizeof(BITMAP),&bmp);
//메모리DC내용을 화면 DC에 복사
BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,hmemDC,0,0,SRCCOPY);
SelectObject(hmemDC,hOldBitmap);
DeleteDC(hmemDC);
ReleaseDC(hWnd,hdc);
}
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
TextOut(hdc,100,100,Mes,strlen(Mes));
EndPaint(hWnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}

'Projects > CoVNC' 카테고리의 다른 글

비트맵 파일 저장하고 읽기  (0) 2007.02.01
CF_BITMAP 사용하기  (0) 2007.01.30
클립보드에서 이미지 읽기  (0) 2007.01.25
Swap16IfLE() 매크로  (0) 2007.01.24
자바 이미지 저장  (0) 2007.01.24
자바 드래그엔 드랍, 클립보드 튜토리얼  (0) 2007.01.23

Swap16IfLE() 매크로

Projects/CoVNC 2007.01.24 22:23 Posted by soulfree >동네청년<
참고 바람 ..

#define Swap16IfLE(s) \
   ((CARD16) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)))

#define Swap32IfLE(l) \
   ((CARD32) ((((l) & 0xff000000) >> 24) | \
    (((l) & 0x00ff0000) >> 8)  | \
  (((l) & 0x0000ff00) << 8)  | \
  (((l) & 0x000000ff) << 24)))




jdlee12 작성:

> big,little endian 은 워드를 저장할때 바이트 앞뒤 순서가 바뀌는 거죠 ..
>
> 다른 OS 와 endian 방식이 다르면
> 매크로로 만들면 1 줄정도 이내로 swap macro 를 만들 수 있읍니다.
>
> "조우현" 작성:
>
> > 안녕하세요.
> > 전 네트워크프로그래밍을 하는데 도움이 필요해서 글을 올립니다.
> > MFC로 만들고 잇는데 다른 시스템의 서버에 client로서 연결하고
> > 또다른 MFC로 만든 클라이언트 프로그램에 대해서는 server로
> > 동작하게하는 말하자만 클라이언트와 서버의 기능을 둘다 가진
> > 프로그램이지요 . 근데 문제가 있습니다. 이 프로그램이 클라이언트로서 서버에
> > 연결할려는 시스템은 windows가 아닌 다른 OS이기때문인데 책을 보면 mfc가 아닌
> > 프로그램에서는 CSocket클래스를 사용할수 없고 big-endian에 맞추어서 데이타를
> > 보내야 한다고 합니다. 정말로 이런 방법 밖에 없나요?
> > 음..제 질문이 너무 복잡한가요?
> > 도움 부탁합니다.

'Projects > CoVNC' 카테고리의 다른 글

CF_BITMAP 사용하기  (0) 2007.01.30
클립보드에서 이미지 읽기  (0) 2007.01.25
Swap16IfLE() 매크로  (0) 2007.01.24
자바 이미지 저장  (0) 2007.01.24
자바 드래그엔 드랍, 클립보드 튜토리얼  (0) 2007.01.23
Cut & Paste 자바 클립보드 - 최종명  (0) 2007.01.23

자바 이미지 저장

Projects/CoVNC 2007.01.24 17:37 Posted by soulfree >동네청년<

jdk 1.4대 버전에서 지원하는 ImageIO클래스를 이용하면 될듯 싶습니다.

--------------------------------------------------------------------------------------------------


import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import java.awt.Color;
import java.io.File;
import javax.imageio.ImageIO;

public class SaveImage {

  public SaveImage() {
  }
  public static void main(String[] args) {

   // 200 x 200 사이즈로 RGB 색생을 이용하는 BufferedImage 객체를 생성한다.
   BufferedImage image = new BufferedImage(200,200, BufferedImage.TYPE_INT_RGB);

   // 그림을 그리기 위해 Graphics2D를 얻어온다.
   Graphics2D graphics = image.createGraphics();

   // 노란색으로 설정한다.
   graphics.setColor(Color.YELLOW);

   // 0,0 부터 200 x 200 사이즈인 사각형으로 채운다.
   graphics.fillRect(0,0,200,200);

   // C:\test.jpeg 파일로 저장한다.
   try {
     File file = new File("C:\\test.jpeg");
     ImageIO.write(image, "jpeg", file);
   }
   catch (Exception e){
     e.printStackTrace();
   }

  }
}

자바 드래그엔 드랍, 클립보드 튜토리얼

Projects/CoVNC 2007.01.23 15:45 Posted by soulfree >동네청년<
http://java.sun.com/docs/books/tutorial/uiswing/dnd/intro.html

Cut & Paste 자바 클립보드 - 최종명

Projects/CoVNC 2007.01.23 14:23 Posted by soulfree >동네청년<

Cut & Paste
-최종명
java.awt.datatransfer 패키지에서 클립보드를 지원하기 위한 클래스들이 정의되어 있다.
현재 JDK 1.1버전에서 지원되는 클립보드는 아직 초보적인 수준이어서 문자열의
cut, copy, paste 기능만 지원한다. 다른 타입을 위한 기능은 추후에 첨가될 예정이다.

전송될 데이타를 가지고 있는 클래스는 Tansferable 인터페이스를 임플리멘츠해주어야 한다.

DataFlavor 클래스는 클립보드로 전송될 데이타의 MIME 타입을 제공하기 위해 사용된다.

Clipboard 클래스는 cut, copy, paste 기능을 제공한다.


COPY 절차
1. java.awt.Toolkit 클래스의 getSYstemClipboard() 메소드를 이용해서 클립보드를
생성한다.

2. Tansferable 인터페이스를 임플리멘츠한 클래스(ex, StringSelection)를 생성한다.

3. Tansferable 인터페이스를 임플리멘츠한 클래스를 클립보드에 setContents() 메소드를
이용해서 붙인다.
예:
  public void copy(TextField tf)  {
   StringSelection data = new StringSelection(tf.getText());
   Clipboard clipboard = Toolkit().getDefaultToolkit().getSystemClipboard();
   clipboard.setContents(data, data);
  }


PASTE 절차
1. java.awt.Toolkit 클래스의 getSystemClipboard() 메소드를 이용해서 클립보드를
생성한다.

2. 클립보드의 getContents() 메소드를 이용해서 클립보드의 내용을 얻는다.

3. getTransferData() 메소드를 이용해서 원하는 데이타를 얻는다.

4. 얻어진 데이타를 적당한 타입으로 변환한다.
예:
  public void paste(TextField tf)  {
   Clipboard clipboard = Toolkit().getDefaultToolkit().getSystemClipboard();
   Transferable data = clipboard.getContents(this);
   String s;
   try {
     s = (String) (data.getTransferData(DataFlavor.stringFlavor));
   } catch (Exception e) {
     s = data.toString();
   }
   tf.setText(s);
  }


예제: CutNPaste.java 파일


    1  import java.io.*;
    2  import java.awt.*;
    3  import java.awt.datatransfer.*;
    4  import java.awt.event.*;
    5  
    6
    7  public class CutNPaste extends Frame implements ActionListener {
    8      TextField tf;
    9      TextArea ta;
   10      String  selection = "";
   11
   12      public static void main (String args[]) {
   13          new CutNPaste().show();
   14      }
   15
   16      public CutNPaste() {
   17          super("Cut & Paste Example");
   18          add(tf = new TextField("클립보드 예제 프로그램입니다."), "North");
   19          add(ta = new TextArea(), "Center");
   20          MenuBar mb = new MenuBar();
   21          mb.add(makeEditMenu());
   22          setMenuBar(mb);
   23          setSize(250, 250);
   24      }
   25
   26      Menu makeEditMenu() {
   27          Menu editMenu = new Menu("Edit");
   28          MenuItem mi = new MenuItem("Cut");
   29          mi.addActionListener(this);
   30          editMenu.add(mi);
   31          mi = new MenuItem("Copy");
   32          mi.addActionListener(this);
   33          editMenu.add(mi);
   34          mi = new MenuItem("Paste");
   35          mi.addActionListener(this);
   36          editMenu.add(mi);
   37          mi = new MenuItem("Clear");
   38          mi.addActionListener(this);
   39          editMenu.add(mi);
   40  
   41          return editMenu;
   42      }
   43  
   44      public void actionPerformed (ActionEvent evt) {
   45          Clipboard clipboard = getToolkit().getSystemClipboard();
   46          String cmd = evt.getActionCommand();
   47          if (cmd.equalsIgnoreCase("copy")) {
   48              selection = tf.getSelectedText();
   49              if(selection == null || selection.length() == 0)
   50                  selection = tf.getText();
   51              StringSelection data = new StringSelection(selection);
   52              clipboard.setContents(data, data);
   53          } else if (cmd.equalsIgnoreCase("clear")) {
   54              tf.setText("");
   55          } else if (cmd.equalsIgnoreCase("paste")) {
   56              Transferable clipData = clipboard.getContents(this);
   57              String s;
   58              try {
   59                  s = (String)(clipData.getTransferData(DataFlavor.stringFlavor));
   60              } catch (Exception e) {
   61                  s = e.toString();
   62              }
   63              ta.append(s+"\n");
   64          } else if (cmd.equalsIgnoreCase("cut")) {
   65              StringSelection data = new StringSelection(tf.getText());
   66              clipboard.setContents(data, data);
   67              tf.setText("");
   68          }
   69      }
   70  }