Мне нужно создать образ кадра, используя кусок изображения.
Например:
Пользователь загрузит фрагмент изображения из исходного кода:
Теперь мне нужно создать фрейм на front-end в соответствии с требованиями пользователя переднего плана (пользователь будет выбирать высоту и ширину рамки, а затем выбрать эту часть изображения) следующим образом:
Я не получаю никакого способа сделать это, я попытался сделать это css и html canvas, но не повезло.
Может кто-нибудь, пожалуйста, предложите мне, как я могу достичь этого, используя PHP или CSS или HTML или JavaScript или любой способ.
Здесь вы можете увидеть рабочий пример, который мне действительно нужно сделать.
Создайте свой собственный кадр
Независимо от того, сделали ли вы вручную, или на лету как-то через библиотеку GD, вам абсолютно необходимо взять изображение, которое вы заявляете, что получаете …
… и обрезайте и затяните его, чтобы сделать его таким же (без белого пространства вокруг краев и выреза или выреза)
Тогда у вас есть образ, с которым вы можете работать.
ПРИМЕЧАНИЕ. Я не делаю javascript здесь. Он будет использоваться для динамического определения размера элемента, как показано в html.
Обычно я бы использовал разумное количество элементов :before
и ': after', чтобы сохранить html менее загроможденным, но поскольку вам требуется динамическая калибровка фрейма, нам нужно использовать несколько вложенных элементов div для установки динамических стилей для ширины и высоты, которые имеют решающее значение для некоторых из элементов div
(некоторые из которых все равно будут псевдоэлементами, если javascript может получить доступ к этим или если динамическая калибровка не нужна).
ПРИМЕЧАНИЕ. Пока я тестировал это только в Chrome и Firefox. На самом деле старые браузеры наверняка потерпят неудачу.
/* 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); }
тем/* 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); }
того, как/* 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>
Я много пробовал создавать фрейм с помощью одного изображения через php, но не нашел никакого решения в php.
С помощью двух ответов (ответ Lucky Soni и ответ ScottS) я создал сценарий, чтобы полностью заполнить мое требование (большое спасибо обоим).
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; }
Теперь я могу создать правильный кадр из любого типа изображения
<?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
Я смотрю ваше решение, это достаточно хорошо. Но я заметил несколько вещей, когда я пытался увеличить высоту и ширину, это не дало соответствующего результата.
Я попытался решить эту проблему, используя разные размеры изображения.
$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 размерах, чтобы мы могли использовать эти размеры при создании кадра в разном соотношении.
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.
Надеюсь, это будет полезно для вас