How to draw a shape using part of image in php

I need to create a frame image using a piece of image.

Example:

The user will download a fragment of the image from the source code:

enter image description here

Now I need to create a frame on the front-end in accordance with the requirements of the foreground user (the user will select the height and width of the frame, and then select this part of the image) as follows:

enter image description here

I do not get any way to do this, I tried to do this using css and html canvas but no luck.

Can someone suggest me how I can achieve this using PHP or CSS or HTML or JavaScript or any way.

Here you can see a working example that I really need to do.

Create your own frame

+54
javascript html css php html5-canvas
Nov 04 '15 at 6:09
source share
5 answers

Image pre-processing is vital

Made manually by you or on the fly somehow through the GD library, you absolutely need to take an image that you claim to receive ...

enter image description here

... and cut and tighten it to make it the same (without white space around the edges and cut or cut))

enter image description here

Then you have an image that you can really work with.

Otherwise, PURE CSS / JAVASCRIPT

NOTE. I do not do javascript here. It will be used to dynamically determine the size of an element, as shown in html.

Normally I would use a reasonable amount of :before and ': after' pseudo-elements to keep html less cluttered, but since you need dynamic frame calibration, then we need to use several nested div elements to set dynamic styles for width and height that are decisive value for some div elements (some of which will still be pseudo-elements if javascript can access them or if dynamic sizing is not required).

NOTE. So far I have only tested this on Chrome and Firefox. In fact, older browsers are likely to fail.

 /* 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> 
+45
Nov 10 '15 at 1:02
source share

The sample you sent in response may not be the best to use when creating a frame. You should get 2 different images for the horizontal and vertical sides of the frame. The bevel and the ribs can also be different images, which can be located respectively.

  .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 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> 
+15
Nov 07 '15 at 17:38
source share

I tried a lot to create a frame using a single image via php, but did not find any solution in php.

With two answers (Lucky Soni's answer and ScottS's answer) I created a script to completely fill my requirement (thanks to both of them).

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; } 

Now I can create the correct frame from any type of image

+5
Dec 01 '15 at 11:25
source share
 <?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); 

try

snippet from: http://www.phpforkids.com/php/php-gd-library-drawing-shapes.php

+2
Nov 13 '15 at 3:58
source share

I look at your decision, that's good enough. But I noticed a few things when I tried to increase the height and width, this did not give the corresponding result.

I tried to solve this problem using different image sizes.

 $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); 

I cropped that part of the image in 4 sizes so that we can use these sizes when creating a frame in a different ratio.

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.

Now you just need to set the ratio for all image sizes, for example:

 //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. 

I hope it will be useful for you

+1
Dec 03 '15 at 5:50
source share



All Articles