웹에서 이미지를 바이너리로 읽어서 새이미지로 저장이 가능한지요?

arka의 이미지


PHP도 초보이고 나머지 프로그래밍도 겉핧기정도입니다.

먼저 하고픈 기능은 파일속에 포함되어 있는 썸네일 이미지를 바이너리로 읽어들여서

썸네일파일로 저장이 가능한가 입니다.

오토캐드 확장자인 *dwg 파일은 내부에 썸네일을 가지고있습니다. (첨부한 pdf파일을 확인하시고)

인터넷에서 구한 소스는 비베소스이고 파일을 불러와서 썸네일을 보여주는 소스입니다.

private void button1_Click(object sender, EventArgs e)

{

Image image = GetThumbnailFromDwg(@"파일이름.dwg");

pictureBox1.Image = image;

}

Bitmap GetThumbnailFromDwg(string fileName)

{

using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

{

using (BinaryReader br = new BinaryReader(fs))

{

fs.Seek(0xD, SeekOrigin.Begin);

fs.Seek(0x14 + br.ReadInt32(), SeekOrigin.Begin);

byte bytCnt = br.ReadByte();

if (bytCnt <= 1)

return null;

int imageHeaderStart;

int imageHeaderSize;

byte imageCode;

for (short i = 1; i <= bytCnt; i++)

{

imageCode = br.ReadByte();

imageHeaderStart = br.ReadInt32();

imageHeaderSize = br.ReadInt32();

if (imageCode == 2) // (R14 ~ 2009)

{

fs.Seek(imageHeaderStart, SeekOrigin.Begin);

br.ReadBytes(0xE);

ushort biBitCount = br.ReadUInt16();

br.ReadBytes(4);

uint biSizeImage = br.ReadUInt32();

fs.Seek(imageHeaderStart, SeekOrigin.Begin);

byte[] bitmapBuffer = br.ReadBytes(imageHeaderSize);

uint colorTableSize = (uint)((biBitCount< 9) ? 4 * Math.Pow(2, biBitCount) : 0);

using (MemoryStream ms = new MemoryStream())

{

using (BinaryWriter bw = new BinaryWriter(ms))

{

bw.Write((ushort)0x4D42);

bw.Write(54U + colorTableSize + biSizeImage);

bw.Write(new ushort());

bw.Write(new ushort());

bw.Write(54U + colorTableSize);

bw.Write(bitmapBuffer);

return new Bitmap(ms);

}

}

}

else if (imageCode == 6) // (2010 ~ 2014)

{

fs.Seek(imageHeaderStart, SeekOrigin.Begin);

using (MemoryStream ms = new MemoryStream())

{

fs.CopyTo(ms, imageHeaderStart);

Image img = Image.FromStream(ms);

return new Bitmap(img);

}

}

else if (imageCode == 3)

{

return null;

}

}

}

}

return null;

}

하지만 웹에서 가능한지... 가능하다면 어떻게 해야할지 , 검색해도 이부분에 있어서는 검색이 안되더군요.

이미지를 리사이징해서 썸네일로 변환하는 php 소스는 아주 간단했습니다.

파라메터값이 좀 많긴했지만...

$original_path="images/original.gif";
$origin_img=imagecreatefromgif($original_path);
$new_img=imagecreatetruecolor(200,100); // 가로 200 픽셀, 세로 100 픽셀
imagecopyresampled($new_img, $origin_img, 0, 0, 0, 0, 200, 100, 500, 300);
$save_path="images/resized.gif";
imagegif($new_img, $save_path);

방법좀 가르켜주시면 감사하겠습니다.

혹시 예제소스라도 있으시면 링크 부탁드립니다.

File attachments: 
첨부파일 크기
PDF icon OpenDesign_Specification_for_.dwg_files.pdf532.82 KB
chanik의 이미지

올려주신 코드는 아래 페이지에 있던 샘플인 것 같은데요.
http://blog.daum.net/cafeofhtewinter/527

php로 포팅해봤습니다.
원 코드는 dwg 파일을 열어서 추출한 썸네일의 Bitmap 오브젝트를 반환하는 식이지만
php에서는 썸네일을 bmp 파일로 저장하도록 했습니다.
.net과 php 모두 잘 모르는 상태에서 연습삼아 해 본 것이니 감안하시고,
적당히 고쳐서 쓰세요. 오류처리하는 코드도 전혀 없습니다.

일단 아래 페이지에서 dwg 샘플을 받아서 돌려보니 동작은 되는 것 같습니다.
http://usa.autodesk.com/adsk/servlet/index?linkID=9240618&id=12456726&siteID=123112

#!/usr/bin/env php
<?php
/* machine byte order unpack functions : little-endian in x86 */
function readInt32($f)  { $s = unpack("l", fread($f, 4)); return $s[1]; }
function readUInt32($f) { $s = unpack("L", fread($f, 4)); return $s[1]; }
function readInt16($f)  { $s = unpack("s", fread($f, 2)); return $s[1]; }
function readUInt16($f) { $s = unpack("S", fread($f, 2)); return $s[1]; }
function readInt8($f)   { $s = unpack("c", fread($f, 1)); return $s[1]; }
function readUInt8($f)  { $s = unpack("C", fread($f, 1)); return $s[1]; }
 
/* machine byte order pack functions : little-endian in x86 */
function writeInt32($f, $s)  { return fwrite($f, pack("l", $s)); }
function writeUInt32($f, $s) { return fwrite($f, pack("L", $s)); }
function writeInt16($f, $s)  { return fwrite($f, pack("s", $s)); }
function writeUInt16($f, $s) { return fwrite($f, pack("S", $s)); }
function writeInt8($f, $s)   { return fwrite($f, pack("c", $s)); }
function writeUInt8($f, $s)  { return fwrite($f, pack("C", $s)); }
 
function GetThumbnailFromDwg($fileName, $thumbfileName)
{
    $f = fopen($fileName, "r");
 
    fseek($f, 0xD);
    $offset   = readInt32($f);
    fseek($f, 0x14 + $offset);
    $bytCnt   = readUInt8($f);
 
    if ($bytCnt <= 1)
        return NULL;
 
    for ($i = 1; $i <= $bytCnt; $i++)
    {
        $imageCode        = readUInt8($f);
        $imageHeaderStart = readInt32($f);
        $imageHeaderSize  = readInt32($f);
 
        if ($imageCode == 2) // (R14 ~ 2009)
        {
            fseek($f, $imageHeaderStart);
            fseek($f, 0xE, SEEK_CUR);
            $biBitCount = readUInt16($f);
            fseek($f, 4, SEEK_CUR);
            $biSizeImage = readUInt32($f);
            fseek($f, $imageHeaderStart);
            $bitmapBuffer = fread($f, $imageHeaderSize);
            $colorTableSize = ($biBitCount < 9) ? 4 * pow(2, $biBitCount) : 0;
 
            $fo = fopen($thumbfileName, "w");
            writeUInt16($fo, 0x4D42);
            writeUInt32($fo, 54 + $colorTableSize + $biSizeImage);
            writeUInt16($fo, 0);
            writeUInt16($fo, 0);
            writeUInt32($fo, 54 + $colorTableSize);
            fwrite($fo, $bitmapBuffer);
            fclose($fo);
 
            return 1;
        }
        //TODO: 아래 경우는 제대로 포팅된 것인지 의심스러움. 확인할 dwg 파일 샘플 없음.
        else if ($imageCode == 6) // (2010 ~ 2014)
        {
            fseek($imageHeaderStart);
 
            $fo = fopen($thumbfileName, "w");
            while(!feof($f))
            {
                $buf = fread($f, $imageHeaderStart);
                fwrite($fo, $buf);
            }
            fclose($fo);
 
            return 1;
        }
        else if ($imageCode == 3)
        {
            return NULL;
        }
    }
    return NULL;
}
 
foreach (glob("samples/*.dwg") as $dwgfile) {
    GetThumbnailFromDwg($dwgfile, $dwgfile . ".bmp");
}
?>
arka의 이미지

else if ($imageCode == 6) // (2010 ~ 2014)
{
fseek($f, $imageHeaderStart);

위에서 빠진부분이 있어서 동작안했었지만 작동잘됩니다.
몇가지 테스트를 해봐야 겠지만 현재로선 어려운 부분이 해결되어 기분이 좋네요.

chanik의 이미지

제가 인터넷에서 구한 dwg 파일은 모두 "if ($imageCode == 2) // (R14 ~ 2009)" 에 해당되어
"else if ($imageCode == 6) // (2010 ~ 2014)" 인 경우의 코드는 테스트할 수 없었습니다.

말씀하신 fseek()의 버그만 고치면, ($imageCode == 6)인 경우도 잘 동작하나요?

arka의 이미지

2000 버전 2004 버젼 2012 버전까지 작동 잘됩니다.
감사합니다.

ps. 이전에 똑같은 내용으로 답변납겼는데 익스플로러 오류인지 등록이안되었네요.

chanik의 이미지

확인 감사합니다.

전에 올린 코드는 C#의 using 문을 무시하고 서둘러 포팅하다보니
fopen()한 파일에 대해 fclose()는 하지 않은채로 return 할 가능성이 있었습니다.
php에서 그런식으로 자원관리를 무시했을때 실제로 부작용이 생기는지는 모르겠지만
어쨌든 그런 경우를 없애기 위해 조금 수정해둔 코드를 올립니다.

#!/usr/bin/env php
<?php
/* machine byte order unpack functions : little-endian in x86 */
function readInt32($f)  { $s = unpack("l", fread($f, 4)); return $s[1]; }
function readUInt32($f) { $s = unpack("L", fread($f, 4)); return $s[1]; }
function readInt16($f)  { $s = unpack("s", fread($f, 2)); return $s[1]; }
function readUInt16($f) { $s = unpack("S", fread($f, 2)); return $s[1]; }
function readInt8($f)   { $s = unpack("c", fread($f, 1)); return $s[1]; }
function readUInt8($f)  { $s = unpack("C", fread($f, 1)); return $s[1]; }
 
/* machine byte order pack functions : little-endian in x86 */
function writeInt32($f, $s)  { return fwrite($f, pack("l", $s)); }
function writeUInt32($f, $s) { return fwrite($f, pack("L", $s)); }
function writeInt16($f, $s)  { return fwrite($f, pack("s", $s)); }
function writeUInt16($f, $s) { return fwrite($f, pack("S", $s)); }
function writeInt8($f, $s)   { return fwrite($f, pack("c", $s)); }
function writeUInt8($f, $s)  { return fwrite($f, pack("C", $s)); }
 
/* class for auto fclose() */
class AutoFile
{
    private $f = NULL;
    function __construct($path, $mode) {
        $this->f = fopen($path, $mode);
    }
    function __destruct() {
        if($this->f)    fclose($this->f);
    }
    public function getf() {
        return $this->f;
    }
}
 
function GetThumbnailFromDwg($fileName, $thumbfileName)
{
    $f_auto = new AutoFile($fileName, "rb");
    $f      = $f_auto->getf();
    if(!$f)
        return NULL;
 
    fseek($f, 0xD);
    $offset   = readInt32($f);
    fseek($f, 0x14 + $offset);
    $bytCnt   = readUInt8($f);
 
    if ($bytCnt <= 1)
        return NULL;
 
    for ($i = 1; $i <= $bytCnt; $i++)
    {
        $imageCode        = readUInt8($f);
        $imageHeaderStart = readInt32($f);
        $imageHeaderSize  = readInt32($f);
 
        if ($imageCode == 2) // (R14 ~ 2009)
        {
            fseek($f, $imageHeaderStart);
            fseek($f, 0xE, SEEK_CUR);
            $biBitCount = readUInt16($f);
            fseek($f, 4, SEEK_CUR);
            $biSizeImage = readUInt32($f);
            fseek($f, $imageHeaderStart);
            $bitmapBuffer = fread($f, $imageHeaderSize);
            $colorTableSize = ($biBitCount < 9) ? 4 * pow(2, $biBitCount) : 0;
 
            $fo_auto = new AutoFile($thumbfileName, "wb");
            $fo      = $fo_auto->getf();
            if(!$fo)
                return NULL;
            writeUInt16($fo, 0x4D42);
            writeUInt32($fo, 54 + $colorTableSize + $biSizeImage);
            writeUInt16($fo, 0);
            writeUInt16($fo, 0);
            writeUInt32($fo, 54 + $colorTableSize);
            fwrite($fo, $bitmapBuffer);
            return 1;
        }
        //TODO: 아래 경우는 제대로 포팅된 것인지 의심스러움. 확인할 dwg 파일 샘플 없음.
        else if ($imageCode == 6) // (2010 ~ 2014)
        {
            fseek($f, $imageHeaderStart);
 
            $fo_auto = new AutoFile($thumbfileName, "wb");
            $fo      = $fo_auto->getf();
            if(!$fo)
                return NULL;
            while(!feof($f))
            {
                $buf = fread($f, $imageHeaderStart);
                fwrite($fo, $buf);
            }
            return 1;
        }
        else if ($imageCode == 3)
        {
            return NULL;
        }
    }
    return NULL;
}
 
foreach (glob("samples/*.dwg") as $dwgfile) {
    GetThumbnailFromDwg($dwgfile, $dwgfile . ".bmp");
}
?>
arka의 이미지

감사합니다.
위 소스로 XE에 페이지를 만들고 열어서 첨부된 파일에대해 썸네일추출후 보여줄려고했는데
첨부파일은 기존의파일과는 달라서 소스적용이 안되는듯합니다.
추가로 검토중인 것이 elfinderxe 라는 XE모듈입니다.
업로드시 이미지파일은 썸네일을 만들어서 보여줍니다. 여기에 dwg썸네일도 추가하고싶은데 알아보기가 힘드네요.
http://tuwlab.com/computer/9086
http://www.xpressengine.com/index.php?mid=download&category_srl=18322923&search_keyword=ELFINDER&package_srl=21643227
웹기반의 파일매니져인데 아직 부족한부분이 많이 보이지만 나름 유용할것같아 소스를 살피는 중입니다만
썸네일생성부분이 쉽게 알아볼수 있게 되어 있지는 않습니다.
많은기능을 가지고가다보니 저처럼 초급자에겐 무리네요.
아래는 소스 일부분입니다.섬네일 생성부분인데 무슨 라이브러리를 이용하는거 같기도 하구요. ^^;
모듈 첨부합니다.
xe 1.5 버전에서 동작하기에 링크해둡니다.
http://mhlee.nflint.com/index.php?mid=board0&document_srl=117

/**
* Return true if required file can be resized.
* By default - the same as canCreateTmb
*
* @param string $path thumnbnail path
* @param array $stat file stat
* @return string|bool
* @author Dmitry (dio) Levashov
**/
protected function canResize($path, $stat) {
return $this->canCreateTmb($path, $stat);
}

/**
* Create thumnbnail and return it's URL on success
*
* @param string $path file path
* @param string $mime file mime type
* @return string|false
* @author Dmitry (dio) Levashov
**/
protected function createTmb($path, $stat) {
if (!$stat || !$this->canCreateTmb($path, $stat)) {
return false;
}

$name = $this->tmbname($stat);
$tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$name;

// copy image into tmbPath so some drivers does not store files on local fs
if (($src = $this->_fopen($path, 'rb')) == false) {
return false;
}

if (($trg = fopen($tmb, 'wb')) == false) {
$this->_fclose($src, $path);
return false;
}

while (!feof($src)) {
fwrite($trg, fread($src, 8192));
}

$this->_fclose($src, $path);
fclose($trg);

$result = false;

$tmbSize = $this->tmbSize;

if (($s = getimagesize($tmb)) == false) {
return false;
}

/* If image smaller or equal thumbnail size - just fitting to thumbnail square */
if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' );

} else {

if ($this->options['tmbCrop']) {

/* Resize and crop if image bigger than thumbnail */
if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize) ) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
}

if (($s = getimagesize($tmb)) != false) {
$x = $s[0] > $tmbSize ? intval(($s[0] - $tmbSize)/2) : 0;
$y = $s[1] > $tmbSize ? intval(($s[1] - $tmbSize)/2) : 0;
$result = $this->imgCrop($tmb, $tmbSize, $tmbSize, $x, $y, 'png');
}

} else {
$result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, true, $this->imgLib, 'png');
$result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' );
}

}
if (!$result) {
unlink($tmb);
return false;
}

return $name;
}

/**
* Resize image
*
* @param string $path image file
* @param int $width new width
* @param int $height new height
* @param bool $keepProportions crop image
* @param bool $resizeByBiggerSide resize image based on bigger side if true
* @param string $destformat image destination format
* @return string|false
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function imgResize($path, $width, $height, $keepProportions = false, $resizeByBiggerSide = true, $destformat = null) {
if (($s = @getimagesize($path)) == false) {
return false;
}

$result = false;

list($size_w, $size_h) = array($width, $height);

if ($keepProportions == true) {

list($orig_w, $orig_h, $new_w, $new_h) = array($s[0], $s[1], $width, $height);

/* Calculating image scale width and height */
$xscale = $orig_w / $new_w;
$yscale = $orig_h / $new_h;

/* Resizing by biggest side */

if ($resizeByBiggerSide) {

if ($orig_w > $orig_h) {
$size_h = $orig_h * $width / $orig_w;
$size_w = $width;
} else {
$size_w = $orig_w * $height / $orig_h;
$size_h = $height;
}

} else {
if ($orig_w > $orig_h) {
$size_w = $orig_w * $height / $orig_h;
$size_h = $height;
} else {
$size_h = $orig_h * $width / $orig_w;
$size_w = $width;
}
}
}

switch ($this->imgLib) {
case 'imagick':

try {
$img = new imagick($path);
} catch (Exception $e) {

return false;
}

$img->resizeImage($size_w, $size_h, Imagick::FILTER_LANCZOS, true);

$result = $img->writeImage($path);

return $result ? $path : false;

break;

case 'gd':
if ($s['mime'] == 'image/jpeg') {
$img = imagecreatefromjpeg($path);
} elseif ($s['mime'] == 'image/png') {
$img = imagecreatefrompng($path);
} elseif ($s['mime'] == 'image/gif') {
$img = imagecreatefromgif($path);
} elseif ($s['mime'] == 'image/xbm') {
$img = imagecreatefromxbm($path);
}

if ($img && false != ($tmp = imagecreatetruecolor($size_w, $size_h))) {
if (!imagecopyresampled($tmp, $img, 0, 0, 0, 0, $size_w, $size_h, $s[0], $s[1])) {
return false;
}

if ($destformat == 'jpg' || ($destformat == null && $s['mime'] == 'image/jpeg')) {
$result = imagejpeg($tmp, $path, 100);
} else if ($destformat == 'gif' || ($destformat == null && $s['mime'] == 'image/gif')) {
$result = imagegif($tmp, $path, 7);
} else {
$result = imagepng($tmp, $path, 7);
}

imagedestroy($img);
imagedestroy($tmp);

return $result ? $path : false;

}
break;

}

return false;
}

/**
* Crop image
*
* @param string $path image file
* @param int $width crop width
* @param int $height crop height
* @param bool $x crop left offset
* @param bool $y crop top offset
* @param string $destformat image destination format
* @return string|false
* @author Dmitry (dio) Levashov
* @author Alexey Sukhotin
**/
protected function imgCrop($path, $width, $height, $x, $y, $destformat = null) {
if (($s = @getimagesize($path)) == false) {
return false;
}

$result = false;

switch ($this->imgLib) {
case 'imagick':

try {
$img = new imagick($path);
} catch (Exception $e) {

return false;
}

$img->cropImage($width, $height, $x, $y);

$result = $img->writeImage($path);

return $result ? $path : false;

break;

case 'gd':
if ($s['mime'] == 'image/jpeg') {
$img = imagecreatefromjpeg($path);
} elseif ($s['mime'] == 'image/png') {
$img = imagecreatefrompng($path);
} elseif ($s['mime'] == 'image/gif') {
$img = imagecreatefromgif($path);
} elseif ($s['mime'] == 'image/xbm') {
$img = imagecreatefromxbm($path);
}

if ($img && false != ($tmp = imagecreatetruecolor($width, $height))) {

if (!imagecopy($tmp, $img, 0, 0, $x, $y, $width, $height)) {
return false;
}

if ($destformat == 'jpg' || ($destformat == null && $s['mime'] == 'image/jpeg')) {
$result = imagejpeg($tmp, $path, 100);
} else if ($destformat == 'gif' || ($destformat == null && $s['mime'] == 'image/gif')) {
$result = imagegif($tmp, $path, 7);
} else {
$result = imagepng($tmp, $path, 7);
}

imagedestroy($img);
imagedestroy($tmp);

return $result ? $path : false;

}
break;
}

return false;
}

댓글 첨부 파일: 
첨부파일 크기
Package icon elfinderxe.zip299.76 KB
chanik의 이미지

XE는 아마 제로보드를 이어서 좀 더 일반화한 소프트웨어인 모양이군요. 웹하드 기능을 제공하는 제3의 소프트웨어인 elfinder라는 것을 포장해서 XE용 모듈로 만든 것이 elFinderXE이고요. (문제되는 부분은 아니지만 라이센스가 LGPLv2, BSD, GPLv2 등 제각각이네요)

소스를 예시해주신대로, elfinder 패키지의 elFinderVolumeDriver.class.php 안에 썸네일 만드는 기능이 들어있는데, 그 작업과정에 이미지 라이브러리로 'gd'를 쓸 수도 있고 'imagick'을 쓸 수도 있는 모양입니다. gd는 bmp 포맷을 지원하지 않아서 dwg에서 추출한 bmp를 다룰 수 없으므로, imagick을 쓰는 경우에만 dwg 썸네일 지원이 가능하겠습니다.

아래의 세 부분을 수정해 봤습니다.

  1. 마임타입 추가 : 'dwg' => 'image/x-dwg'
  2. canCreateTmb() : 'imagick'을 쓸 경우에는 .dwg 파일에 대해서도 TRUE를 반환하도록 수정
  3. createTmb() : .dwg 파일의 경우 미리 .bmp를 추출하고 이것을 .png로 변환하도록 예외처리

수정한 코드는 아래와 같습니다. 저는 웹작업에 익숙치 않아 위의 패키지들을 설치하고 돌려보려면 배보다 배꼽이 더 커지게 되므로 동작확인까지는 하지 못했습니다. 이를 감안하시고 그냥 출발점 정도로 삼으시면 좋겠습니다.

--- xe/modules/elfinderxe/includes/php/elFinderVolumeDriver.class.php   2013-02-02 02:12:56.000000000 +0900
+++ xe/modules/elfinderxe/includes/php/elFinderVolumeDriver.class.php.new   2013-11-28 14:56:17.000000000 +0900
@@ -380,6 +380,7 @@
        'ai'    => 'image/vnd.adobe.photoshop',
        'xbm'   => 'image/xbm',
        'pxm'   => 'image/pxm',
+       'dwg'   => 'image/x-dwg',   // kldp.org/node/140618
        //audio
        'mp3'   => 'audio/mpeg',
        'mid'   => 'audio/midi',
@@ -2548,7 +2549,8 @@
            && strpos($path, $this->tmbPath) === false // do not create thumnbnail for thumnbnail
            && $this->imgLib
            && strpos($stat['mime'], 'image') === 0
-           && ($this->imgLib == 'gd' ? $stat['mime'] == 'image/jpeg' || $stat['mime'] == 'image/png' || $stat['mime'] == 'image/gif' : true);
+           && ($this->imgLib == 'gd' ? $stat['mime'] == 'image/jpeg' || $stat['mime'] == 'image/png' || $stat['mime'] == 'image/gif' : true)
+           && ($stat['mime'] == 'image/x-dwg' ? $this->imgLib == 'imagick' : true);   // kldp.org/node/140618
    }
 
    /**
@@ -2580,22 +2582,39 @@
        $name = $this->tmbname($stat);
        $tmb  = $this->tmbPath.DIRECTORY_SEPARATOR.$name;
 
-       // copy image into tmbPath so some drivers does not store files on local fs
-       if (($src = $this->_fopen($path, 'rb')) == false) {
-           return false;
-       }
+       // kldp.org/node/140618
+       if ($stat['mime'] == 'image/x-dwg') {
+           $dwgbmp = $tmb.".bmp";
+           if(GetThumbnailFromDwg($path, $dwgbmp) /* && $this->imgLib == 'imagick' */) {
+               try {
+                   $img = new imagick($dwgbmp);
+               } catch (Exception $e) {
+                   return false;
+               }
 
-       if (($trg = fopen($tmb, 'wb')) == false) {
-           $this->_fclose($src, $path);
-           return false;
-       }
+               if(!$img->writeImage($tmb))
+                   return false;
 
-       while (!feof($src)) {
-           fwrite($trg, fread($src, 8192));
-       }
+               unlink($dwgbmp);
+           }
+       } else {
+           // copy image into tmbPath so some drivers does not store files on local fs
+           if (($src = $this->_fopen($path, 'rb')) == false) {
+               return false;
+           }
 
-       $this->_fclose($src, $path);
-       fclose($trg);
+           if (($trg = fopen($tmb, 'wb')) == false) {
+               $this->_fclose($src, $path);
+               return false;
+           }
+
+           while (!feof($src)) {
+               fwrite($trg, fread($src, 8192));
+           }
+
+           $this->_fclose($src, $path);
+           fclose($trg);
+       }
 
        $result = false;

TODO: GD 라이브러리에 빠져있는 imagecreatefrombmp() 함수를 사람들이 나름대로 구현한 코드가 돌아다니는 것 같습니다. google 뒤지면 많이 나오는데 그 가운데 제대로 구현된 것을 찾아 쓰면 'gd'를 쓰는 경우에도 dwg 썸네일 처리가 가능해질 것입니다.

댓글 첨부 파일: 
첨부파일 크기
파일 elFinderVolumeDriver.class_.php_.tgz18.32 KB
chanik의 이미지

이전에 올린 코드는 php에 Imagick이 설치되어 있어야 동작이 가능한데 (사실 제대로 테스트된 코드도 아니지만..), 시스템에는 보통 Imagick이 없는 것 같더군요. 그래서 GD 라이브러리 상에서 동작할 수 있도록 수정했습니다.

이 코드를 쓰면 dwg 파일 업로드할 때 썸네일이 만들어집니다. 그런데 dwg에서 추출된 bmp 파일 중 처리되는 않는 것도 있네요. 인터넷에 굴러다니는 imagecreatefrombmp()를 몇 개 가져다 테스트해봤는데 마찬가지였습니다. 제가 테스트했던 imagecreatefrombmp() 버전들은 모두 묶어 첨부했으니 참고하시고요.

안정적으로 bmp -> png 변환할 방법만 찾으면 잘 동작할 것 같습니다.

TODO:

  1. php에 Imagick 패키지를 설치해서 쓴다. ( $ sudo pecl install imagick )
  2. 시스템에 ImageMagick 이 설치되어 있다면, system("convert image.bmp image.png"); 식의 php 코드로 해결.
  3. 다양한 bmp를 지원하는 imagecreatefrombmp()를 찾아본다.

GD 라이브러리 위에서 동작하는 PHP Image Magician 이란 것이 있기에 가져다 실험해봤는데, imagecreatefrombmp()과 마찬가지였습니다.

잘 안되는 bmp 파일과 그 bmp 파일을 추출했던 dwg 파일도 첨부했습니다.
( dwg 파일 출처: http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=12456726&linkID=9240618 )

댓글 첨부 파일: 
chanik의 이미지

 

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.