인터넷 쇼핑몰 등의 사이트에서 유용하게 쓰일 수 있다.
==================================================================================================
[GIF]
- width 정보 : 6~7번째 바이트 / Short Endian 으로 합침
- height 정보 : 8~9번째 바이트 / Short Endian 으로 합침
--------------------------------------------------------------------------------------------------
[JPEG]
- 4 바이트를 읽어들임
- marker 정보: 2~3 번째 바이트 / Big Endian 으로 합침
- skip size 정보: 3~4 번째 바이트 / Big Endian 으로 합침
- marker 정보가 지원하는 SOF marker 인지 확인
- 지원하는 marker 가 발견될 경우 추가 6바이트를 읽어 들임
( 0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf 중 하나)
- width 정보 : 읽어들인 6 바이트에서 1~2 바이트 / Big Endian 으로 합침
- height 정보 : 읽어들인 6 바이트에서 3~4 바이트 / Big Endian 으로 합침
- 위의 단계 중 4번째 단계에서 지원하는 marker가 발견되지 않을 경우 2번째 단계에서 산출한
skipsize에서 2를 뺀 바이트 만큼을 skip하고 다시 1부터 루프를 돌림.
==================================================================================================
* Short Endian: 2 바이트로 구성된 값을 논리합 할 때 하위 비트를 큰 값으로(8비트 좌향 shift) 연산한다.
* Big Endian: short endian과 반대로 상위 비트를 8비트 좌향 shift 시켜 하위 비트와 논리합한다.
==================================================================================================
/*
* File : ImgSize.java
* brief : Get ImgFile's width and height
*/
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
public class ImgSize
{
private int width;
private int height;
private InputStream in;
public boolean check()
{
width = 0;
height = 0;
try
{
// read()함수를 통해 읽은 정수값이 음수일 수 있기 때문
int b1 = read() & 0xff;
int b2 = read() & 0xff;
// 0xff (0x000000ff)로 마스크 함으로써 32비트 정수값의 첫 비트에 있는 음수 비트를 없애주기 위함
if(0x47 == b1 && 0x49 == b2)
{
return chkGIF();
}
else if(0xff == b1 && 0xd8 == b2)
{
return chkJPG();
}
else
{
return false;
}
}catch(IOException ioe)
{
return false;
}
}
private boolean chkGIF() throws IOException
{
final byte[] GIF_MAGIC_87A = {0x46, 0x38, 0x37, 0x61};
final byte[] GIF_MAGIC_89A = {0x46, 0x38, 0x39, 0x61};
byte[] a = new byte[11];
if(read(a) != 11)
{
return false;
}
if((!equals(a, 0, GIF_MAGIC_87A, 0, 4)) &&
(!equals(a, 0, GIF_MAGIC_89A, 0, 4)))
{
return false;
}
width = getLittleEndian(a, 4);
height = getLittleEndian(a, 6);
return (width >0 && height > 0);
}
private boolean chkJPG() throws IOException
{
byte[] data = new byte[12];
while(true)
{
if( read(data, 0, 4) != 4)
{
return false;
}
int marker = getBigEndian(data, 0);
int size = getBigEndian(data, 2);
if((marker & 0xff00) != 0xff00)
{
return false;
}
if(marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 &&
marker != 0xffc8)
{
if(read(data, 0, 6) != 6)
{
return false;
}
width = getBigEndian(data, 3);
height = getBigEndian(data, 1);
return (width >0 && height > 0);
}
else
{
skip(size -2);
}
}
}
private boolean equals(byte[] a1, int offs1, byte[] a2, int offs2, int num)
{
while(num-- > 0)
{
if(a1[offs1++] != a2[offs2++])
{
return false;
}
}
return true;
}
// byte값에 0xff를 masking 한 다음, 두 값을 논리합하고 있다.
// 이 때 상위 byte를 8비트 좌향 shift 시키고, 하위 byte를 논리합하는데,
// 이렇게 함으로써 16 비트의 공간의 각각 반에 상위 바이트와 하위 바이트를 위치 시킬 수 있다.
private int getBigEndian(byte[] a, int offs)
{
return (a[offs] & 0xff) << 8 | (a[offs + 1]& 0xff);
}
// 아래와 같은 방법으로 값을 뽑아낼 수 있다.
// 상위비트: (a >> 8) & 0xff
// 하위비트: a & 0xff
private int getLittleEndian(byte[] a, int offs)
{
return (a[offs] & 0xff) | (a[offs + 1]& 0xff) << 8;
}
private int read() throws IOException
{
return in.read();
}
private int read(byte[] a)throws IOException
{
if (in != null)
{
return in.read(a);
}
return 0;
}
private int read(byte[] a, int offset, int num) throws IOException
{
if(in != null)
{
return in.read(a, offset, num);
}
return 0;
}
private void skip(int num) throws IOException
{
in.skip(num);
}
public int getHeiht()
{
return height;
}
public int getWidth()
{
return width;
}
public boolean SetImage(String imagepath)
{
try
{
in = new FileInputStream(imagepath);
return check();
}
catch(Exception e)
{
return false;
}
finally {
try{
if(in != null) in.close(); } catch(Exception ie){}
}
}
public ImgSize() {}
public static void main(String[] args) {
ImgSize imgsize = new ImgSize();
if(imgsize.SetImage("bbb.gif"))
{
System.out.println("width : " + imgsize.getWidth());
System.out.println("height : " + imgsize.getHeiht());
}
}
}
'IT_Programming > Java' 카테고리의 다른 글
Java performance tips (0) | 2008.09.08 |
---|---|
DB 관련된 한글 처리 방법 (0) | 2008.09.08 |
Java 기타 튜닝법 (0) | 2008.09.07 |
JAVA Tip & Tuning Technic (0) | 2008.09.07 |
[펌] Annotation (주석) (0) | 2008.08.28 |