/** * Creates new BMP file from image resource * @param resource $img Image resource to convert * @param string $file File to save image to. If ommited or "", file is written to standard output * @param boolean $useRLE When true, file will be saved with RLE compression (EXPERIMENTAL) * @return boolean True when successfully writen to specified file */ function imagebmp($img, $file = "", $useRLE = false) { $ColorCount = imagecolorstotal($img); $Transparent = imagecolortransparent($img); $IsTransparent = $Transparent != -1; if ($IsTransparent) { $ColorCount--; } if ($ColorCount == 0) { $ColorCount = 0; $BitCount = 24; $palsize = 0; } if ($ColorCount > 0 and $ColorCount <= 2) { $ColorCount = 2; $BitCount = 1; } if ($ColorCount > 2 and $ColorCount <= 16) { $ColorCount = 16; $BitCount = 4; } if ($ColorCount > 16 and $ColorCount <= 256) { $ColorCount = 0; $BitCount = 8; } $Width = imagesx($img); $Height = imagesy($img); $Zbytek = (4 - $Width / (8 / $BitCount) % 4) % 4; if ($BitCount < 24) { $palsize = pow(2, $BitCount) * 4; } $size = (floor($Width / (8 / $BitCount)) + $Zbytek) * $Height + 54; $size += $palsize; $offset = 54 + $palsize; // Bitmap File Header $ret = 'BM'; // header (2b) $ret .= jpexs_int_to_dword($size); // size of file (4b) $ret .= jpexs_int_to_dword(0); // reserved (4b) $ret .= jpexs_int_to_dword($offset); // byte location in the file which is first byte of IMAGE (4b) // Bitmap Info Header $ret .= jpexs_int_to_dword(40); // Size of BITMAPINFOHEADER (4b) $ret .= jpexs_int_to_dword($Width); // width of bitmap (4b) $ret .= jpexs_int_to_dword($Height); // height of bitmap (4b) $ret .= jpexs_int_to_word(1); // biPlanes = 1 (2b) $ret .= jpexs_int_to_word($BitCount); // biBitCount = {1 (mono) or 4 (16 clr ) or 8 (256 clr) or 24 (16 Mil)} (2b) $ret .= jpexs_int_to_dword($useRLE); // RLE COMPRESSION (4b) $ret .= jpexs_int_to_dword(0); // width x height (4b) $ret .= jpexs_int_to_dword(0); // biXPelsPerMeter (4b) $ret .= jpexs_int_to_dword(0); // biYPelsPerMeter (4b) $ret .= jpexs_int_to_dword(0); // Number of palettes used (4b) $ret .= jpexs_int_to_dword(0); // Number of important colour (4b) // image data $retd = ""; $CC = $ColorCount; $sl1 = strlen($ret); if ($CC == 0) { $CC = 256; } if ($BitCount < 24) { $ColorTotal = imagecolorstotal($img); if ($IsTransparent) { $ColorTotal--; } for ($p = 0; $p < $ColorTotal; $p++) { $color = imagecolorsforindex($img, $p); $ret .= jpexs_inttobyte($color["blue"]); $ret .= jpexs_inttobyte($color["green"]); $ret .= jpexs_inttobyte($color["red"]); $ret .= jpexs_inttobyte(0); //RESERVED } $CT = $ColorTotal; for ($p = $ColorTotal; $p < $CC; $p++) { $ret .= jpexs_inttobyte(0); $ret .= jpexs_inttobyte(0); $ret .= jpexs_inttobyte(0); $ret .= jpexs_inttobyte(0); //RESERVED } } if ($BitCount <= 8) { for ($y = $Height - 1; $y >= 0; $y--) { $bWrite = ""; for ($x = 0; $x < $Width; $x++) { $color = imagecolorat($img, $x, $y); $bWrite .= jpexs_decbinx($color, $BitCount); if (strlen($bWrite) == 8) { $retd .= jpexs_inttobyte(bindec($bWrite)); $bWrite = ""; } } if (strlen($bWrite) < 8 and strlen($bWrite) != 0) { $sl = strlen($bWrite); for ($t = 0; $t < 8 - $sl; $t++) { $sl .= "0"; } $retd .= jpexs_inttobyte(bindec($bWrite)); } for ($z = 0; $z < $Zbytek; $z++) { $retd .= jpexs_inttobyte(0); } } } if ($useRLE and $BitCount == 8) { for ($t = 0; $t < strlen($retd); $t += 4) { if ($t != 0) { if ($t % $Width == 0) { $ret .= chr(0) . chr(0); } } if (($t + 5) % $Width == 0) { $ret .= chr(0) . chr(5) . substr($retd, $t, 5) . chr(0); $t += 1; } if (($t + 6) % $Width == 0) { $ret .= chr(0) . chr(6) . substr($retd, $t, 6); $t += 2; } else { $ret .= chr(0) . chr(4) . substr($retd, $t, 4); } } $ret .= chr(0) . chr(1); } else { $ret .= $retd; } $Dopl = ""; if ($BitCount == 24) { for ($z = 0; $z < $Zbytek; $z++) { $Dopl .= chr(0); } for ($y = $Height - 1; $y >= 0; $y--) { for ($x = 0; $x < $Width; $x++) { $color = imagecolorsforindex($img, ImageColorAt($img, $x, $y)); $ret .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]); } $ret .= $Dopl; } } if ($file != "") { $r = $f = fopen($file, "w"); $r = $r and fwrite($f, $ret); $r = $r and fclose($f); return $r; } else { echo $ret; } }
/** * Creates ico file from image resource(s) * @param resource|array $images Target Image resource (Can be array of image resources) * @param string $filename Target ico file to save icon to, If ommited or "", image is written to snadard output - use header("Content-type: image/x-icon"); */ function imageIco($images, $filename = "") { if (is_array($images)) { $ImageCount = count($images); $Image = $images; } else { $Image[0] = $images; $ImageCount = 1; } $WriteToFile = false; if ($filename != "") { $WriteToFile = true; } $ret = ""; $ret .= jpexs_inttoword(0); //PASSWORD $ret .= jpexs_inttoword(1); //SOURCE $ret .= jpexs_inttoword($ImageCount); //ICONCOUNT for ($q = 0; $q < $ImageCount; $q++) { $img = $Image[$q]; $Width = imagesx($img); $Height = imagesy($img); $ColorCount = imagecolorstotal($img); $Transparent = imagecolortransparent($img); $IsTransparent = $Transparent != -1; if ($IsTransparent) { $ColorCount--; } if ($ColorCount == 0) { $ColorCount = 0; $BitCount = 24; } if ($ColorCount > 0 and $ColorCount <= 2) { $ColorCount = 2; $BitCount = 1; } if ($ColorCount > 2 and $ColorCount <= 16) { $ColorCount = 16; $BitCount = 4; } if ($ColorCount > 16 and $ColorCount <= 256) { $ColorCount = 0; $BitCount = 8; } //ICONINFO: $ret .= jpexs_inttobyte($Width); // $ret .= jpexs_inttobyte($Height); // $ret .= jpexs_inttobyte($ColorCount); // $ret .= jpexs_inttobyte(0); //RESERVED $Planes = 0; if ($BitCount >= 8) { $Planes = 1; } $ret .= jpexs_inttoword($f, $Planes); //PLANES if ($BitCount >= 8) { $WBitCount = $BitCount; } if ($BitCount == 4) { $WBitCount = 0; } if ($BitCount == 1) { $WBitCount = 0; } $ret .= jpexs_inttoword($WBitCount); //BITS $Zbytek = (4 - $Width / (8 / $BitCount) % 4) % 4; $ZbytekMask = (4 - $Width / 8 % 4) % 4; $PalSize = 0; $Size = 40 + ($Width / (8 / $BitCount) + $Zbytek) * $Height + ($Width / 8 + $ZbytekMask) * $Height; if ($BitCount < 24) { $Size += pow(2, $BitCount) * 4; } $IconId = 1; $ret .= jpexs_inttodword($Size); //SIZE $OffSet = 6 + 16 * $ImageCount + $FullSize; $ret .= jpexs_inttodword(6 + 16 * $ImageCount + $FullSize); //OFFSET $FullSize += $Size; //------------- } for ($q = 0; $q < $ImageCount; $q++) { $img = $Image[$q]; $Width = imagesx($img); $Height = imagesy($img); $ColorCount = imagecolorstotal($img); $Transparent = imagecolortransparent($img); $IsTransparent = $Transparent != -1; if ($IsTransparent) { $ColorCount--; } if ($ColorCount == 0) { $ColorCount = 0; $BitCount = 24; } if ($ColorCount > 0 and $ColorCount <= 2) { $ColorCount = 2; $BitCount = 1; } if ($ColorCount > 2 and $ColorCount <= 16) { $ColorCount = 16; $BitCount = 4; } if ($ColorCount > 16 and $ColorCount <= 256) { $ColorCount = 0; $BitCount = 8; } //ICONS $ret .= jpexs_inttodword(40); //HEADSIZE $ret .= jpexs_inttodword($Width); // $ret .= jpexs_inttodword(2 * $Height); // $ret .= jpexs_inttoword(1); //PLANES $ret .= jpexs_inttoword($BitCount); // $ret .= jpexs_inttodword(0); //Compress method $ZbytekMask = $Width / 8 % 4; $Zbytek = $Width / (8 / $BitCount) % 4; $Size = ($Width / (8 / $BitCount) + $Zbytek) * $Height + ($Width / 8 + $ZbytekMask) * $Height; $ret .= jpexs_inttodword($Size); //SIZE $ret .= jpexs_inttodword(0); //HPIXEL_M $ret .= jpexs_inttodword(0); //V_PIXEL_M $ret .= jpexs_inttodword($ColorCount); //UCOLORS $ret .= jpexs_inttodword(0); //DCOLORS //--------------- $CC = $ColorCount; if ($CC == 0) { $CC = 256; } if ($BitCount < 24) { $ColorTotal = imagecolorstotal($img); if ($IsTransparent) { $ColorTotal--; } for ($p = 0; $p < $ColorTotal; $p++) { $color = imagecolorsforindex($img, $p); $ret .= jpexs_inttobyte($color["blue"]); $ret .= jpexs_inttobyte($color["green"]); $ret .= jpexs_inttobyte($color["red"]); $ret .= jpexs_inttobyte(0); //RESERVED } $CT = $ColorTotal; for ($p = $ColorTotal; $p < $CC; $p++) { $ret .= jpexs_inttobyte(0); $ret .= jpexs_inttobyte(0); $ret .= jpexs_inttobyte(0); $ret .= jpexs_inttobyte(0); //RESERVED } } if ($BitCount <= 8) { for ($y = $Height - 1; $y >= 0; $y--) { $bWrite = ""; for ($x = 0; $x < $Width; $x++) { $color = imagecolorat($img, $x, $y); if ($color == $Transparent) { $color = imagecolorexact($img, 0, 0, 0); } if ($color == -1) { $color = 0; } if ($color > pow(2, $BitCount) - 1) { $color = 0; } $bWrite .= jpexs_decbinx($color, $BitCount); if (strlen($bWrite) == 8) { $ret .= jpexs_inttobyte(bindec($bWrite)); $bWrite = ""; } } if (strlen($bWrite) < 8 and strlen($bWrite) != 0) { $sl = strlen($bWrite); for ($t = 0; $t < 8 - $sl; $t++) { $sl .= "0"; } $ret .= jpexs_inttobyte(bindec($bWrite)); } for ($z = 0; $z < $Zbytek; $z++) { $ret .= jpexs_inttobyte(0); } } } if ($BitCount >= 24) { for ($y = $Height - 1; $y >= 0; $y--) { for ($x = 0; $x < $Width; $x++) { $color = imagecolorsforindex($img, imagecolorat($img, $x, $y)); $ret .= jpexs_inttobyte($color["blue"]); $ret .= jpexs_inttobyte($color["green"]); $ret .= jpexs_inttobyte($color["red"]); if ($BitCount == 32) { $ret .= jpexs_inttobyte(0); } //Alpha for ICO_XP_COLORS } for ($z = 0; $z < $Zbytek; $z++) { $ret .= jpexs_inttobyte(0); } } } //MASK for ($y = $Height - 1; $y >= 0; $y--) { $byteCount = 0; $bOut = ""; for ($x = 0; $x < $Width; $x++) { if ($Transparent != -1 and imagecolorat($img, $x, $y) == $Transparent) { $bOut .= "1"; } else { $bOut .= "0"; } } for ($p = 0; $p < strlen($bOut); $p += 8) { $byte = bindec(substr($bOut, $p, 8)); $byteCount++; $ret .= jpexs_inttobyte($byte); } $Zbytek = $byteCount % 4; for ($z = 0; $z < $Zbytek; $z++) { $ret .= jpexs_inttobyte(0xff); } } //------------------ } //q if ($WriteToFile) { $f = fopen($filename, "w"); fwrite($f, $ret); fclose($f); } else { echo $ret; } }