Home  >  Article  >  Backend Development  >  Simulate getimagesizefromstring function below php5.4

Simulate getimagesizefromstring function below php5.4

WBOY
WBOYOriginal
2016-07-25 08:55:09794browse
  1. if($in = fopen('php://input', "rb"))
  2. while($buff = fread($in, 4096))
  3. fwrite('e:\1.jpg' , $buff);
Copy the code

To get the image information, the only way is getimagesize($filename) and open the file you just closed again. There is a getimagesizefromstring in php, but it requires >=php5.4.

Is there a way to directly manipulate the data stream? The answer is yes, there is "Supported Protocols and Encapsulation Protocols" in the official PHP manual, and the data:// in it should be familiar to everyone.

You can use it to directly manipulate images (watermarks, thumbnails, etc.) in the data stream. For convenience, the following code is directly file_get_contents().

  1. $file_path = 'http://www.baidu.com/img/shouye_b5486898c692066bd2cbaeda86d74448.gif';
  2. $stream = file_get_contents($file_path);
  3. print_r(getimagesize( "data: //text/plain;base64," . base64_encode($stream)));
  4. $new_img = imagecreatefromgif("data://text/plain;base64," . base64_encode($stream));//or $new_img = imagecreatefromstring($stream);
  5. print_r($new_img);
  6. imagejpeg($new_img, 'E:WEBuploadstest.jpg', 100);
Copy code

The format was successfully converted.

This method is good, but base64 doesn't look so cool.

You can consider a simpler method, stream_register_wrapper — register a URL wrapper protocol implemented with a PHP class.

Code:

  1. class getImgStream{

  2. private $imgStream;
  3. private $position;
  4. function stream_open($path, $mode, $options, &$opened_path){
  5. $url = parse_url($path);
  6. $this->imgStream = $GLOBALS[$url["host"]];
  7. $this->position = 0;
  8. return true;
  9. }

  10. function stream_read($count){

  11. $ret = substr($this->imgStream, $this->position, $count);
  12. $this->position += strlen($ret) ;
  13. return $ret;
  14. }
  15. function stream_stat(){
  16. //maxmemory: 5 * 1024 * 1024;
  17. $fp = fopen("php://temp/maxmemory:5242880", 'r+');
  18. fwrite ($fp, $this->imgStream);
  19. $fstat = fstat($fp);
  20. fclose($fp);
  21. return $fstat;
  22. }

  23. function stream_eof() {

  24. return $this->position >= strlen($this->imgStream);
  25. }

  26. function stream_tell(){

  27. return $this->position;
  28. }
  29. function stream_close(){
  30. unset($this->imgStream, $this->position);
  31. }
  32. }

  33. $file_path = 'http://www.baidu. com/img/shouye_b5486898c692066bd2cbaeda86d74448.gif';

  34. $stream = file_get_contents($file_path);

  35. stream_wrapper_register("image", "getImgStream");

  36. < p> print_r(getimagesize('image://stream'));
  37. $new_img = imagecreatefromgif('image://stream');//or $new_img = imagecreatefromstring($stream);
  38. print_r($new_img);
  39. imagejpeg ($new_img, 'E:WEBuploadstest.jpg', 100);

Copy the code

No surprises, because this function supports PHP 4 >= 4.3.0, PHP 5.

After testing, the same local picture (300x800), the average method 1 is 43ms, the average method 2 is 39ms

Correction: If the stream reported by getimagesize does not support seeking, you may need to add the seek operation to the wrapper and add the code:

  1. function stream_seek($offset, $whence){
  2. $l = strlen($this->imgStream);
  3. $p = &$this->position;
  4. switch($whence){
  5. case SEEK_SET: $newPos = $offset;
  6. break;
  7. case SEEK_CUR: $newPos = $p + $offset;
  8. break;
  9. case SEEK_END: ​​$newPos = $l + $offset;
  10. break;
  11. default: return false;
  12. }
  13. $ret = ($newPos >= 0 && $newPos <= $l);
  14. if($ret)
  15. $p = $newPos;
  16. return $ret;
  17. }
Copy code


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn