상세 컨텐츠

본문 제목

[Flex&Flash] useCodePage = true 가 한글 또는 다른언어 깨짐 방지, 언어상관없이 프로그램 만들기 관련 대한 이견 관련

ADOBE/ ActionScript

by AlrepondTech 2020. 9. 23. 02:21

본문

반응형

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

출처: http://blog.flashplatform.kr/195

 

안녕하세요? 검쉰입니다. 오랫만에 블로그 포스트로 인사드립니다.
그동안 티스토리에서 문제가 되었던 Flash Player 10에서 swf 로드가 안되던 문제가 해결이 되었네요. ;) 기존의 제 포스트들도 정상으로 보이고요. 이사하려다가 그 것또한 귀차니즘에 의해 좌절. ^ㅂ^; 아무튼 다시 오랫만에 글로 인사드려요. ;^)

흔히 자주 쓰시는 Flash로 만든 네비케이터 바 에서 메뉴정보를 외부의 XML 로 받아오는 경우와 같이 외부의 데이터를 읽어오는 과정에서 한글이 깨지는 경험을 한번쯤은 하셨을 겁니다. 이런 경우 커뮤니티에서 검색해보시면 System.useCodePage = true; 를 넣어라. 라는  답변을 많이 볼 수 있습니다. 심지여 이 것을 "한글 깨짐 방지 코드"라고 부르는 경우도 있더군요. 옛 속담에 '선무당이 사람잡는다'라는 이야기가 있습니다. 정확하게 이해하지 못하고 쓰게 되면 뒷일 감당하기 힘들게 되는 법!!. 왜 System.useCodePage = true; 를 넣으면 한글이 안꺠지는지 알아보도록 하겠습니다.

'EUC-KR' 이라고 많이 보셨을 겁니다. 한글을 정의한 캐릭터 셋(charset)입니다. 보통 한글 윈도우에서 제작한 파일은 'EUC-KR' 캐릭터 셋으로 저장되는 경우가 많습니다. 이 때 캐릭터 셋이란 글자들의 집합을 정의한 것이라고 생각하시면 됩니다. (보다 자세한 건 위키백과의 설명을 참조하시길 바랍니다.) 
이러한 캐릭터 셋이 다르게 되어 있는 데이터를 읽어오게 되면 한글이 깨지게 되는데요, Flash 내부에서는 유니코드(UTF-8)를 기본으로 사용하기 때문입니다. 'EUC-KR'로 제작된 파일을 'UTF-8'로 읽었으니 당연히 서로 다른 캐릭터 셋을 사용하게 되므로 한글이 깨지게 되는 겁니다. 이러한 경우에 바로 System.useCodePage = true; 를 사용하면 한글이 깨어지지 않는데, 그 이유는 LiveDocs 에도 잘 나와있습니다. 

useCodePage 속성  

useCodePage:Boolean  [읽기/쓰기]

언어 버전: ActionScript 3.0
런타임 버전: AIR 1.0, Flash Player 9

Flash Player에서 외부 텍스트 파일을 해석하는 데 사용할 코드 페이지를 지정하는 부울 값입니다. 이 속성을 false로 설정하면 외부 텍스트 파일이 유니코드로 해석됩니다. 이러한 파일은 저장할 때 유니코드로 인코딩되어야 합니다. 이 속성을 true로 설정하면 외부 텍스트 파일이 Flash Player가 실행되는 운영 체제의 일반 코드 페이지로 해석됩니다. useCodePage의 기본값은 false입니다.

flash.display.Loader.load(), flash.net.URLLoader, flash.net.URLStream 또는 XML 클래스를 사용하여 외부 파일로 로드하는 텍스트를 Flash Player에서 유니코드로 인식하려면 이러한 파일을 유니코드로 저장해야 합니다. 외부 파일을 유니코드로 인코딩하려면 Windows 2000의 메모장과 같이 유니코드를 지원하는 응용 프로그램에서 파일을 저장해야 합니다.

유니코드로 인코딩되지 않은 외부 텍스트 파일을 로드하려면 useCodePage를 true로 설정합니다. 이렇게 하려면 데이터를 로드하는 SWF 파일의 첫 번째 프레임에 다음 코드를 첫 코드 행으로 추가합니다.

System.useCodePage = true;

이 코드를 추가하면 외부 텍스트가 Flash Player가 실행되고 있는 운영 체제의 일반 코드 페이지로 해석됩니다. 영문 Windows 운영 체제의 경우 대개 CP1252이고 한국어 운영 체제의 경우 EUC-KR입니다. 만약 useCodePage를 true로 설정하면 Flash Player 6 이상 버전은 Flash Player 5와 같은 방법으로 텍스트를 처리합니다. Flash Player 5에서는 모든 텍스트를 Flash Player 실행 운영 체제의 일반 코드 페이지를 사용하는 것으로 간주하고 처리했습니다.

useCodePage를 true로 설정하는 경우 플레이어가 실행되는 운영 체제의 일반 코드 페이지에 외부 텍스트 파일에 사용되는 문자가 포함되어 있어야 텍스트가 표시됩니다. 예를 들어 중국어 문자가 포함된 외부 텍스트 파일을 로드하는 경우 CP1252 코드 페이지에는 중국어 문자가 없으므로 이 코드 페이지를 사용하는 시스템에서 중국어 문자가 표시되지 않습니다.

모든 플랫폼에서 SWF 파일에 사용된 외부 텍스트 파일을 볼 수 있게 하려면 모든 외부 텍스트 파일을 유니코드로 인코딩하고 useCodePagefalse로 설정된 상태로 두어야 합니다. 이렇게 하면 Flash Player 6 이상에서 텍스트가 유니코드로 해석됩니다.


LiveDocs 에도 나와 있는 것 처럼 useCodePage 를 true로 설정하면 유니코드가 아닌 운영체제의 codepage로 해석이 되는 것이죠. 한글 윈도우의 기본 codePage는 'EUC-KR(51949)' 입니다. 그래서 외부의 'EUC-KR'로 되어있는 문서가 깨지지 않고 읽히게 되는 것입니다. 

더 이상의 문제가 없어보입니다만,  실제 그렇지 않습니다. 해당 swf 를 로드하는 사용자가 외국어 OS를 사용하고 있다면 어떨까요? 열심히 만든 어플을 정식으로 런칭했는데, 그걸 외국의 한국인이 본다면???

이론적으로 보면 'EUC-KR'로 되어 있는 문서를 해당 OS의 codePage로 읽게 될텐데, 다른 언어의 OS는 codePage가 설마 'EUC-KR(51949)'일까요?? 위의 livedocs의 설명에도 나와 있듯, 다른 나라의 OS는 한국어 OS와 codePage가 다르다는 군요. (다른 나라 언어의 캐릭터 셋에 대해서 궁금하시다면 여기에서 확인해보시면 되겠습니다.)

실제로 그런지 확인을 위해서 아래와 같은 간단한 swf 파일을 만들어 봤습니다. 소스코드는 다음과 같습니다.
Flex 로 만든 App. 

view plaincopy to clipboardprint?

  1. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" fontSize="12" width="250" height="250">  
  2.     <mx:Script>  
  3.         <![CDATA[  
  4.         private function init():void  
  5.         {  
  6.             System.useCodePage = true;  
  7.           
  8.             var loader:URLLoader = new URLLoader();  
  9.             configureListeners(loader);  
  10.           
  11.             var request:URLRequest = new URLRequest("./assets/xml/data(euc-kr).xml");  
  12.           
  13.             try   
  14.             {  
  15.                 loader.load(request);  
  16.             }   
  17.             catch (error:Error)   
  18.             {  
  19.                 trace("Unable to load requested document.");  
  20.             }  
  21.         }  
  22.           
  23.         private function configureListeners(dispatcher:IEventDispatcher):void   
  24.         {  
  25.             dispatcher.addEventListener(Event.COMPLETE, completeHandler);  
  26.             dispatcher.addEventListener(Event.OPEN, openHandler);  
  27.             dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);  
  28.             dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);  
  29.             dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);  
  30.             dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);  
  31.         }  
  32.           
  33.         private function completeHandler(event:Event):void {  
  34.             var loader:URLLoader = URLLoader(event.target);  
  35.             trace("completeHandler: " + loader.data);  
  36.             var myXML:XML = new XML(loader.data.toString());  
  37.               
  38.             myTextArea.text = myXML.FLEX.DESC[0];  
  39.         }  
  40.           
  41.         private function openHandler(event:Event):void {  
  42.             trace("openHandler: " + event);  
  43.         }  
  44.           
  45.         private function progressHandler(event:ProgressEvent):void {  
  46.             trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);  
  47.         }  
  48.           
  49.         private function securityErrorHandler(event:SecurityErrorEvent):void {  
  50.             trace("securityErrorHandler: " + event);  
  51.         }  
  52.           
  53.         private function httpStatusHandler(event:HTTPStatusEvent):void {  
  54.             trace("httpStatusHandler: " + event);  
  55.         }  
  56.           
  57.         private function ioErrorHandler(event:IOErrorEvent):void {  
  58.             trace("ioErrorHandler: " + event);    
  59.         }  
  60.         ]]>  
  61.     </mx:Script>  
  62.     <mx:TextArea id="myTextArea" right="10" left="10" top="38" bottom="10"/>  
  63.     <mx:Label text="System.useCodePage = true;" top="10" left="10"/>  
  64. </mx:Application>  


로드한 XML 파일

view plaincopy to clipboardprint?

  1. <ROOT>  
  2.     <FLEX>  
  3.         <DESC>  
  4.             <![CDATA[ Adobe Flex Builder 3 소프트웨어는 Eclipse™ 기반의 개발 툴로서 ... 
  5.             ]]>  
  6.         </DESC>  
  7.     </FLEX>  
  8. </ROOT>  




동일한 XML 파일을 'UTF-8', 'EUC-KR'로 각각 저장해서 useCodePage를 각각 false, true 로 설정해 영어, 일어 Windows 에서 IE로 읽어봤습니다. 
클릭하셔서 확인해보세요.










Windows XP 영문판에서 swf 로드





Windows XP 일어판에서 swf 로드



UTF-8로 되어있는 파일은 어떤 OS든지 간에 잘 로드가 되고 있고, 'EUC-KR'로 되어있는 것을 System.useCodePage = true; 로 설정한 것은 한글이 여지없이 깨져보이는 것을 확인 할 수 있습니다. 외국에 서비스 할 생각이 없는 어플이라 하더라도, 기본적으로 'UTF-8'로 파일들을 저장해 놓으시면 한글문제를 잘 피해가실 수 있다고 생각합니다. 단순이 파일만이 아니라, HTTPService로 load 하는 데이터 또한 'UTF-8' 로 제작되어야 하겠죠?

하지만 할 수 없이 'EUC-KR'을 사용해야 할 때가 있습니다.네이버 카페의 경우 'EUC-KR'로 되어 있는데요, 이 것 때문에 useCodePage를 true로 설정할 수 는 없는 것 아니겠습니까? 이런 고민을 제가 존경하는 원강민님께서 블로그에 이미 포스팅 하신 적이 있습니다.
System.useCodePage 대신 이렇게.. 이 포스트를 참고 하시면 좋겠습니다.

간만에 글을 썼더니 꽤나 길어졌네요 :-) 다들 좋은 주말 되시길!

 

 

=================================

=================================

=================================

 

 

 

출처: http://airdev.tistory.com/397

 

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

 

function readMultiEncodingText(bytes:ByteArray):String

{

//UTF-8 with BOM

if(bytes[0] == 0xEF)if(bytes[1] == 0xBB)if(bytes[2] == 0xBF) return bytes.toString();

 

//UTF-16 Big Endian

if(bytes[0] == 0xFE)if(bytes[1] == 0xFF) return bytes.toString();

 

//UTF-16 Little Endian

if(bytes[0] == 0xFF)if(bytes[1] == 0xFE) return bytes.toString();

 

//UTF-32 Big Endian

if(bytes[0] == 0x0)if(bytes[1] == 0x0)if(bytes[2] == 0xFE)if(bytes[3] == 0xFF) return bytes.toString();

 

//UTF-32 Little Endian

if(bytes[0] == 0xFF)if(bytes[1] == 0xFE)if(bytes[2] == 0x0)if(bytes[3] == 0x0) return bytes.toString();

 

//기타

var ansiStr:String = bytes.readMultiByte(bytes.bytesAvailable, "ANSI");

var unicodeStr:String = bytes.toString();

 

if(ansiStr.length < unicodeStr.length) return ansiStr;

 

return unicodeStr;

}

 

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

System.useCodePage = true; 많이들 쓰시나요? 요즘은 UTF-8이 대세여서 그런지 별로 쓸 일이 없습니다..그런데 이번에 RSS 리더를 개발하던 중 문제가 생겼습니다..

RSS 리더에서 불러들인 페이지들의 경우 UTF-8이 아닌 것도 있다는 거죠..네이버 카페가 대표적입니다..EUC-KR을 쓰죠..

EUC-KR의 경우 System.useCodePage = true;를 사용하면 해결됩니다..
그런데 지금 만드는건 RSS리더잖아요..즉, UTF-8도 있고 EUC-KR도 있습니다..다른 인코딩도 있겠죠..
System.useCodePage를 true, false로 변경하면서 해당하는 웹 페이지를 불러오면 될까요?
물론 어느정도 딜레이를 준다면 가능할 듯 합니다..하지만 그렇게 구현하는건 왠지 아닌거 같죠? 속도가 빨라야 하니까요..

그래서 위와 같은 함수를 만들게 되었습니다..
BOM만으로는 UTF-8을 정확하게 잡을 수가 없습니다..없는 경우도 있으니까요..

처음 코드는 위와 달리 조금 더 복잡했습니다..encodeURI()도 사용했고 바이트 어레이를 좀 더 복잡하게 다뤘죠..몇번의 테스트 끝에 위의 코드가 나왔는데요..아래 예제에 적용해 봤습니다..
아직 UTF-8, EUC-KR, UCS2 Big/Little Endian만 테스트를 했을 뿐입니다..즉, 앞으로 다른 경우가 생길 경우 업데이트를 해야 한다는 뜻이죠..

찾게 되면 업데이트 하겠습니다..

* 아래 예제에서는 텍스트를 뿌려줄 때 부하를 막기 위해 800자 까지만 보이도록 했습니다..
** 페이지를 불러올 때 인코딩 정보를 정확하게 알 수 있는 좋은 방법이 있다면 알려주세요^^

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://lpesign.tistory.com/entry/URLLoaderDataFormatVARIABLES-%EA%B3%BC-%ED%95%9C%EA%B8%80%EA%B9%A8%EC%A7%90-%ED%98%84%EC%83%81

 

URLLoader 한글깨짐 현상

 

예전 AS2 LoadVar 시절, 외부데이터를 이용할 경우 

System.useCodePage = true 한방이면 거의 모든게 해결이 되었다.

하지만 점점 까탈스러워지는 as...

 

 

 

 

먼저 useCodePage 레퍼런스내용

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

외부 텍스트 파일을 해석하는 데 사용할 코드 페이지를 지정하는 부울 값입니다. 이 속성을 false로 설정하면 외부 텍스트 파일이 유니코드로 해석됩니다. 이러한 파일은 저장할 때 유니코드로 인코딩되어야 합니다. 이 속성을 true로 설정하면 외부 텍스트 파일이 응용 프로그램이 실행되는 운영 체제의 일반 코드 페이지로 해석됩니다. useCodePage의 기본값은 false입니다

   useCodePage를 true로 설정하는 경우 응용 프로그램이 실행되는 운영 체제의 일반 코드 페이지에 외부 텍스트 파      일에 사용되는 문자가 포함되어 있어야 텍스트가 표시됩니다

 

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

 

몬말이냐하면 true로 설정하면 울나라 어지간한 컴터에서는 EUC-KR로 처리한다는 소리.

하지만 문제는 as3에서 URLLoader를 이용할경우

 

dataFormat을 variables로 설정하면 useCodePage를 true로 설정하여도 한글이 깨지게 된다.

 

왜??십ㅁ올밍ㄴ;로민아로미로 왜ㅐㅐㅐㅐㅐㅐ???

 

 

 

 

 

아래는 dataFormat 레퍼런스내용

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

dataFormat : String = "text"

다운로드하는 데이터를 텍스트(URLLoaderDataFormat.TEXT), 원시 이진 데이터(URLLoaderDataFormat.BINARY) 또는 URL 인코딩된 변수(URLLoaderDataFormat.VARIABLES) 중 어떤 형식으로 수신할 것인지 제어합니다.

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

 

URL 인코딩된....URL 인코딩된....URL 인코딩된....URL 인코딩된....URL 인코딩된....URL 인코딩된....URL 인코딩된....

그렇다면 어떻게 해야 할까??

역시 모든해답은 레퍼런스에 있다.

 

 

 

 

 

레 투더 퍼

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

모든 플랫폼에서 응용 프로그램에 사용된 외부 텍스트 파일을 볼 수 있게 하려면 모든 외부 텍스트 파일을 유니코드로 인코딩하고 useCodePage를 false로 설정된 상태로 두어야 합니다. 이렇게 하면 응용 프로그램(Flash Player 6 이상 버전)은 텍스트를 유니코드로 해석합니다.

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

as3에서 URLLoader를 이용할경우

useCodePage는 false로 놔둔채 텍스트를 유니코드로 인코딩채로 받아야 한다.

 

ex)

$txt=iconv("EUC-KR","UTF-8",$txt);

echo $txt;

 

 

하지만 이렇게 쉽게 끊나지않는다.

URLVariables 를 이용해서 데이터를 넘길땐 한글이 깨진다는것 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 어쩔

 

제일 간단한 것은 귀찮더라도 플래시에서 보낼 문자열을 하나하나 URL인코딩해서 넘기는 것이다.

encodeURIComponent () 함수  

public function encodeURIComponent(uri:String):String

언어 버전:  ActionScript 3.0
런타임 버전:  AIR 1.0 Flash Player 9

문자열을 유효한 URI 구성 요소로 인코딩합니다. 문자가 기본 문자의 매우 작은 그룹에 속하지 않은 경우 URI의 하위 문자열을 모든 문자가 UTF-8 이스케이프 시퀀스로 인코딩된 문자열로 변환합니다

위의 함수를 이용하면된다.

 

다른 방법은 그냥 useCodePage를 보낼땐 true로 받을땐 false로 받으면 된다.

 

 예를 들면 URLLoader의 load명령전 System.useCodePage=true; 를 넣고 

open 이벤트가 일어날때 System.useCodePage=false;를 넣어주는 것이다.

 

단 이럴 경우 한글이 그대로 전달되기 때문에 몇몇의 특수문자가 문제를 일으킬수있다 (< > & 등등)

 

 

접기

_req=new URLRequest(서버사이드주소)

_urlLoader=new URLLoader ();
_urlLoader.dataFormat=URLLoaderDataFormat.VARIABLES;
_urlLoader.addEventListener(Event.OPEN,onOpen);
_urlLoader.addEventListener(Event.COMPLETE,onComplete);

private function loadData():void{
     System.useCodePage=true;
     var variables:URLVariables = new URLVariables();
     variables.hangul = "내가고자라니";
     _req.data=variables;
     _urlLoader.load(_req);
}

private function onOpen(e:Event):void{
     System.useCodePage = false;     
}

private function onComplete(e:Event):void{
     trace(_loader.data.hangul)
}

접기

 

 

 

=================================

=================================

=================================

 

 

 

 

반응형


관련글 더보기

댓글 영역