如何在php中使用一张图片绘制一个形状

我需要使用一张图片创build一个帧图像。

例如:

用户将从后端上传图片:

在这里输入图像说明

现在我需要根据前端用户的要求在前端创build一个框架(用户将select框架的高度和宽度,然后他将select这个图片),如下所示:

在这里输入图像说明

我没有办法做到这一点,我试图通过CSS和HTMLcanvas做到这一点,但没有运气。

有人可以请我build议我怎样才能实现这一点,通过使用PHP或CSS或HTML或JavaScript或任何如何。

你可以在这里看到这个工作的例子,实际上我需要做的。

创build你自己的框架

预处理图像至关重要

无论是由您手动完成,还是通过GD库以某种方式完成,您至less需要拍摄您正在接收的图像。

在这里输入图像说明

…和作物,并拧紧,使其像这样干净(没有空白的边缘和切口/切口被删除):

在这里输入图像说明

那么你有一个你可以实际工作的图像。

否则,纯粹的CSS / JAVASCRIPT

注意:我不在这里做javascript。 它将被用来dynamic设置元素大小,如在HTML中所见。

通常我会使用一个明智的数量:before和':后面的'伪元素,以保持html不那么混乱,但既然你需要dynamic调整框架的大小,那么我们需要使用一些嵌套的div元素来设置dynamic样式宽度和高度是一些div元素的关键(如果javascript可以访问这些元素,其中一些仍然是伪元素,或者不需要dynamicresize)。

注意:到目前为止,我只在Chrome和Firefox中testing过。 真的是旧的浏览器肯定会惨败。

 /* implementation of framing */ .frameit { /* width and height must be set dynamically by javascript see html */ position: relative; box-sizing: border-box; overflow: hidden; padding: 20px; /* at least border size */ } .frameit:before, .frameit:after, .frameit .sides > div, .frameit .corner > div { position: absolute; background-image: url(http://i.stack.imgur.com/vAgqj.jpg); background-size: 100% 20px; /* 100% and border size */ height: 20px; /* equal to border width of frameit div */ } .frameit:before { content: ''; top: 0; left: 0; right: 0; } .frameit:after { content: ''; bottom: 0; left: 0; right: 0; } .frameit .sides { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 1; } .frameit .sides > div { /* width must be set dynamically by javascript see html */ height: 20px; } .frameit .sides > div:first-child { top: 0; left: 20px; /* border width */ transform-origin: 0 0; transform: rotate(90deg); } .frameit .sides > div:last-child { bottom: 0; right: 20px; /* border width */ transform-origin: 100% 100%; transform: rotate(90deg); } .frameit .sides ~ .corner { /* all corners */ position: absolute; z-index: 2; width: 29px; /* square root of ((border-width squared) x 2) round up */ height: 29px; /* match width */ overflow: hidden; } .frameit .TL { top: 0; left: 0; transform-origin: 0 0; transform: rotate(-45deg); } .frameit .TL > div { top: inherit; left: inherit; transform-origin: inherit; transform: rotate(45deg); } .frameit .TR { top: 0; right: 0; transform-origin: 100% 0; transform: rotate(45deg); } .frameit .TR > div { top: 0; right: 0; transform-origin: 100% 0; transform: rotate(-45deg); } .frameit .BR { bottom: 0; right: 0; transform-origin: 100% 100%; transform: rotate(-45deg); } .frameit .BR > div { bottom: inherit; right: inherit; transform-origin: inherit; transform: rotate(45deg); } .frameit .BL { bottom: 0; left: 0; transform-origin: 0 100%; transform: rotate(45deg); } .frameit .BL > div { bottom: inherit; left: inherit; transform-origin: inherit; transform: rotate(-45deg); } /* Optional shading to help define the joint */ .frameit .sides > div:first-child:before, .frameit .sides > div:last-child:before { content: ''; position: absolute; top: 0; right: 0; left: 0; bottom: 0; background-color: rgba(0,0,0,.07); } 
 <div class="frameit" style="width: 200px; height: 300px;"> <!-- top and bottom and overall container width and height assumed to be set by javacript by user --> <div class="sides"> <!-- left and right sides widths of the children are equal to HEIGHT of container and are assumed to be set by javacript by user --> <div style="width: 300px;"></div> <div style="width: 300px;"></div> </div> <div class="TL corner"><!-- top left bevel --><div style="width: 200px;"></div></div> <div class="TR corner"><!-- top right bevel --><div style="width: 200px;"></div></div> <div class="BR corner"><!-- bottom right bevel --><div style="width: 200px;"></div></div> <div class="BL corner"><!-- bottom left bevel --><div style="width: 200px;"></div></div> </div> 

您在答案中张贴的示例图片可能不适合用于生成框架。 你应该得到2个不同的图像的水平和垂直两侧的框架。 斜面和边缘也可以是不同的图像,可以相应地定位。

  .frame { position: relative; width: 500px; /*width of the frame*/ } .horizontal-side { /*use a horizontal background that can repeat properly*/ background: url(http://i.stack.imgur.com/high1.jpg) repeat; } .horizontal-side { width: 500px; /*width of the frame*/ height: 20px; } .vertical-side { /*use a vertical background that can repeat properly*/ background: url(http://i.stack.imgur.com/high1.jpg) repeat; width: 20px; height: 400px; /*height of the frame*/ } .vertical-side.right { position: absolute; right: 0; top: 20px; /*same as the horizontal side's hight*/ } 
 <div class="frame"> <div class="horizontal-side top"> </div> <div class="vertical-side left"> </div> <div class="vertical-side right"> </div> <div class="horizontal-side bottom"> </div> </div> 

我已经尝试了很多创build框架使用单个图像通过PHP,但没有find任何解决scheme在PHP中。

在两个答案的帮助下(Lucky Soni的回答和ScottS的回答),我创build了一个脚本来充分满足我的要求(非常感谢两者)。

First I have created 4 images from single image while uploading:

 $file = Input::file('image'); $destinationPath = 'test/'; $filename = time() . $file->getClientOriginalName(); $extension = $file->getClientOriginalExtension(); $upload_success = $file->move($destinationPath, $filename); // This will create image for upper horizontal part $im = new imagick(public_path().'/test/'.$filename); $im->setImageFormat( "jpg" ); $topUperName = 'hr-uper-'.$filename; $img_name = public_path().'/20*20/'.$topUperName; $im->resizeImage(20,20,Imagick::FILTER_LANCZOS,1); $im->writeImage($img_name); // This will create image for vertical right part $vrtRght = 'vrt-right-'.$filename; $img_name = public_path().'/20*20/'.$vrtRght; $im->rotateimage('', '90'); $im->writeImage($img_name); // This will create image for bottom horizontal part $topUperBtm = 'hr-btm-'.$filename; $img_name = public_path().'/20*20/'.$topUperBtm; $im->rotateimage('', '90'); $im->writeImage($img_name); // This will create image for vertical left part $vrtlft = 'vrt-left-'.$filename; $img_name = public_path().'/20*20/'.$vrtlft; $im->rotateimage('', '90'); $im->writeImage($img_name); $im->clear(); $im->destroy(); unlink(public_path() . '/' . $filename); 

HTML layout:

 <div class="frame"> <div class="horizontal-side top"></div> <div class="vertical-side left"></div> <div class="vertical-side right"></div> <div class="horizontal-side bottom"></div> <div class="right-top-corner corner-holder"> <img class="right-top corner" src="<?php echo url(); ?>/20*20/hr-uper-1448949720a.jpg"> </div> <div class="right-btm-corner corner-holder"> <img class="right-btm" corner src="<?php echo url(); ?>/20*20/hr-btm-1448949720a.jpg"> </div> <div class="left-top-corner corner-holder"> <img class="left-top corner" src="<?php echo url(); ?>/20*20/hr-uper-1448949720a.jpg"> </div> <div class="left-btm-corner corner-holder"> <img class="left-btm corner" src="<?php echo url(); ?>/20*20/hr-btm-1448949720a.jpg"> </div> </div> 

Styling

 .frame { position: relative; width: 500px; /* dynamic*/ height: 500px; /* dynamic*/ } .horizontal-side { width: 100%; height: 100px; /* height of image*/ position: absolute; } .horizontal-side.top { background: url('<?php echo url(); ?>/20*20/hr-uper-1448949720a.jpg') repeat !important; } .horizontal-side.bottom { background: url('<?php echo url(); ?>/20*20/hr-btm-1448949720a.jpg') repeat !important; } .horizontal-side.top { top: 0 !important; } .horizontal-side.bottom { bottom: 0 !important; } .vertical-side { width: 100px !important; /* width of image*/ height: 100% !important; z-index: 9 !important; position: absolute !important; } .vertical-side.left { left: 0 !important; background: url('<?php echo url(); ?>/20*20/vrt-left-1448949720a.jpg') repeat !important; } .vertical-side.right { right: 0; background: url('<?php echo url(); ?>/20*20/vrt-right-1448949720a.jpg') repeat !important; } .corner-holder { position: absolute !important; z-index: 9 !important; } .right-top-corner{ right: 0px !important; } .right-btm-corner { bottom: 0 !important; } .left-top-corner{ left: 0 !important; } .left-btm-corner{ bottom: 0 !important; left: 0 !important; } .corner { height: 100px !important; /* corner height (size of image)*/ width: 100px !important; /* corner width (size of image)*/ } .right-top { clip: polygon(100% 0, 0% 100%, 0 0) !important; -webkit-clip-path: polygon(100% 0, 0% 100%, 0 0) !important; -moz-clip-path: polygon(100% 0, 0% 100%, 0 0) !important; -ms-clip-path: polygon(100% 0, 0% 100%, 0 0) !important; -o-clip-path: polygon(100% 0, 0% 100%, 0 0) !important; clip-path: polygon(100% 0, 0% 100%, 0 0) !important; } .right-btm{ clip: polygon(0 100%, 0 0, 100% 100%) !important; -webkit-clip-path: polygon(0 100%, 0 0, 100% 100%) !important; -moz-clip-path: polygon(0 100%, 0 0, 100% 100%) !important; -ms-clip-path: polygon(0 100%, 0 0, 100% 100%) !important; -o-clip-path: polygon(0 100%, 0 0, 100% 100%) !important; clip-path: polygon(0 100%, 0 0, 100% 100%) !important; } .left-top{ clip: polygon(100% 0, 0 0, 100% 100%) !important; -webkit-clip-path: polygon(100% 0, 0 0, 100% 100%) !important; -moz-clip-path: polygon(100% 0, 0 0, 100% 100%) !important; -ms-clip-path: polygon(100% 0, 0 0, 100% 100%) !important; -o-clip-path: polygon(100% 0, 0 0, 100% 100%) !important; clip-path: polygon(100% 0, 0 0, 100% 100%) !important; } .left-btm{ clip: polygon(100% 0, 0 100%, 100% 100%) !important; -webkit-clip-path: polygon(100% 0, 0 100%, 100% 100%) !important; -moz-clip-path: polygon(100% 0, 0 100%, 100% 100%) !important; -ms-clip-path: polygon(100% 0, 0 100%, 100% 100%) !important; -o-clip-path: polygon(100% 0, 0 100%, 100% 100%) !important; clip-path: polygon(100% 0, 0 100%, 100% 100%) !important; } 

现在我可以从任何types的图像创build一个适当的框架

 <?php header('Content-type: image/png'); $png_image = imagecreate(300, 300); $grey = imagecolorallocate($png_image, 229, 229, 229); $green = imagecolorallocate($png_image, 128, 204, 204); imagefilltoborder($png_image, 0, 0, $grey, $grey); imagefilledrectangle ($png_image, 20, 20, 80, 80, $green); // SQUARE imagefilledrectangle ($png_image, 100, 20, 280, 80, $green); // RECTANGLE imagefilledellipse ($png_image, 50, 150, 75, 75, $green); // CIRCLE imagefilledellipse ($png_image, 200, 150, 150, 75, $green); // ELLIPSE $poly_points = array(150, 200, 100, 280, 200, 280); imagefilledpolygon ($png_image, $poly_points, 3, $green); // POLYGON imagepng($png_image); imagedestroy($png_image); 

试试看

该片段来自: http : //www.phpforkids.com/php/php-gd-library-drawing-shapes.php

我看你的解决scheme,这是够好的。 但是我注意到了一些事情,当我试图增加高度和宽度时,没有给出合适的结果。

我试图通过使用不同大小的图像来解决这个问题。

 $file = Input::file('image'); $destinationPath = 'test/'; $filename = time() . $file->getClientOriginalName(); $extension = $file->getClientOriginalExtension(); $upload_success = $file->move($destinationPath, $filename); // This will create image for upper horizontal part $im = new imagick(public_path().'/test/'.$filename); $im->setImageFormat( "jpg" ); /** Here I have created 4 side images of 20*20 **/ $topUperName = 'hr-uper-'.$filename; $img_name = public_path().'/20*20/'.$topUperName; $im->resizeImage(20,20,Imagick::FILTER_LANCZOS,1); $im->writeImage($img_name); // This will create image for vertical right part $vrtRght = 'vrt-right-'.$filename; $img_name = public_path().'/20*20/'.$vrtRght; $im->rotateimage('', '90'); $im->writeImage($img_name); // This will create image for bottom horizontal part $topUperBtm = 'hr-btm-'.$filename; $img_name = public_path().'/20*20/'.$topUperBtm; $im->rotateimage('', '90'); $im->writeImage($img_name); // This will create image for vertical left part $vrtlft = 'vrt-left-'.$filename; $img_name = public_path().'/20*20/'.$vrtlft; $im->rotateimage('', '90'); $im->writeImage($img_name); $im->clear(); $im->destroy(); /** Here I have created 4 side images of 30*30 **/ // This will create image for upper horizontal part $im2 = new imagick(public_path().'/test/'.$filename); $im2->setImageFormat( "jpg" ); $topUperName = 'hr-uper-'.$filename; $img_name = public_path().'/30*30/'.$topUperName; $im2->resizeImage(30,30,Imagick::FILTER_LANCZOS,1); $im2->writeImage($img_name); // This will create image for vertical right part $vrtRght = 'vrt-right-'.$filename; $img_name = public_path().'/30*30/'.$vrtRght; $im2->rotateimage('', '90'); $im2->writeImage($img_name); // This will create image for bottom horizontal part $topUperBtm = 'hr-btm-'.$filename; $img_name = public_path().'/30*30/'.$topUperBtm; $im2->rotateimage('', '90'); $im2->writeImage($img_name); // This will create image for vertical left part $vrtlft = 'vrt-left-'.$filename; $img_name = public_path().'/30*30/'.$vrtlft; $im2->rotateimage('', '90'); $im2->writeImage($img_name); $im2->clear(); $im2->destroy(); /** Here I have created 4 side images of 40*40 **/ // This will create image for upper horizontal part $im3 = new imagick(public_path().'/test/'.$filename); $im3->setImageFormat( "jpg" ); $topUperName = 'hr-uper-'.$filename; $img_name = public_path().'/40*40/'.$topUperName; $im3->resizeImage(40,40,Imagick::FILTER_LANCZOS,1); $im3->writeImage($img_name); // This will create image for vertical right part $vrtRght = 'vrt-right-'.$filename; $img_name = public_path().'/40*40/'.$vrtRght; $im3->rotateimage('', '90'); $im3->writeImage($img_name); // This will create image for bottom horizontal part $topUperBtm = 'hr-btm-'.$filename; $img_name = public_path().'/40*40/'.$topUperBtm; $im3->rotateimage('', '90'); $im3->writeImage($img_name); // This will create image for vertical left part $vrtlft = 'vrt-left-'.$filename; $img_name = public_path().'/40*40/'.$vrtlft; $im3->rotateimage('', '90'); $im3->writeImage($img_name); $im3->clear(); $im3->destroy(); /** Here I have created 4 side images of 50*50 **/ // This will create image for upper horizontal part $im4 = new imagick(public_path().'/test/'.$filename); $im4->setImageFormat( "jpg" ); $topUperName = 'hr-uper-'.$filename; $img_name = public_path().'/50*50/'.$topUperName; $im4->resizeImage(50,50,Imagick::FILTER_LANCZOS,1); $im4->writeImage($img_name); // This will create image for vertical right part $vrtRght = 'vrt-right-'.$filename; $img_name = public_path().'/50*50/'.$vrtRght; $im4->rotateimage('', '90'); $im4->writeImage($img_name); // This will create image for bottom horizontal part $topUperBtm = 'hr-btm-'.$filename; $img_name = public_path().'/50*50/'.$topUperBtm; $im4->rotateimage('', '90'); $im4->writeImage($img_name); // This will create image for vertical left part $vrtlft = 'vrt-left-'.$filename; $img_name = public_path().'/50*50/'.$vrtlft; $im4->rotateimage('', '90'); $im4->writeImage($img_name); $im4->clear(); $im4->destroy(); unlink(public_path() . '/' . $filename); 

我裁剪了4幅图像的这一部分,以便我们可以在创build不同比例的帧时使用这些尺寸。

For example if I am going to create a frame 1000*200, then it was breaking the css, because you were using a image of only 20*20 thick image in all sizes of frame.

现在您只需要设置所有图像大小的比例,例如:

 //you will get this from your ajax call $width = $_GET['width']; $width = $_GET['height']; if($width <= 200){ $frameImage = 'path-of-your-20*20-image'; } if($width > 200 && $width <= 500){ $frameImage = 'path-of-your-30*30-image'; } if($width > 500 && $width <= 700){ $frameImage = 'path-of-your-40*40-image'; } if($width > 700){ $frameImage = 'path-of-your-50*50-image'; } // you can set these variable as per your requirement. And then use this image path to create the html of your frame. If you need a big range of your frame then you can also crop and save image in more sizes while uploading. 

希望这对你有用