How to draw a shape using a piece of image in php
The sample image you have posted in your answer might not be best for usage in generating the frame. You should get 2 different images for horizontal and vertical sides of the frame. The bevel and edges can also be different images that can be positioned accordingly.
.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/vAgqj.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/vAgqj.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>
Updated with the cleaned-up image from @ScottS answer
<?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 that
the snippet is from: http://www.phpforkids.com/php/php-gd-library-drawing-shapes.php
I have tried a lot to create the frame using a single image via php, but did not find any solution in php.
With the help of the two answers (Lucky Soni's answer and ScottS's answer) I have created a script to full fill my requirement (many thanks to both).
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 am able to create a proper frame from any type of image
Preprocessing the image is vital
Whether done manually by you, or on the fly somehow through a GD library, you absolutely at the least need to take the image you state you are receiving...
...and crop and tighten it to make it clean like this (with no white space around the edges and the notch/cut removed):
Then you have an image you can actually work with.
Otherwise, PURE CSS / JAVASCRIPT
NOTE: I am not doing the javascript here. It would be used to dynamically set the element sizing as seen in the html.
Normally I would use a judicious amount of :before
and ':after' pseudo elements to keep the html less cluttered, but since you need dynamic sizing of the frame, then we need to use a number of nested div elements to set dynamic styles for widths and heights that are critical to some of the div
elements (some of which would still be pseudo elements if javascript could access those or if dynamic sizing was not needed).
NOTE: So far I have only tested this in Chrome and Firefox. Really old browsers are for sure going to fail miserably.
/* 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>