Подтвердить что ты не робот

Как нарисовать фигуру с помощью части изображения в php

Мне нужно создать образ кадра, используя кусок изображения.

Пример:

Пользователь загрузит фрагмент изображения из исходного кода:

введите описание изображения здесь

Теперь мне нужно создать фрейм на front-end в соответствии с требованиями пользователя переднего плана (пользователь будет выбирать высоту и ширину кадра, а затем выбрать эту часть изображения) следующим образом:

введите описание изображения здесь

Я не получаю никакого способа сделать это, я пытался сделать это с помощью css и html canvas, но не повезло.

Может кто-нибудь предложить мне, как я могу достичь этого, используя PHP или CSS или HTML или JavaScript или любой способ.

Здесь вы можете увидеть рабочий пример, который мне действительно нужно сделать.

Создайте свой собственный кадр

4b9b3361

Ответ 1

Предварительная обработка изображения имеет жизненно важное значение

Сделано вручную вами или на лету как-то через библиотеку GD, вам абсолютно необходимо взять изображение, которое вы заявляете, что получаете...

введите описание изображения здесь

... и обрезайте и затяните его, чтобы сделать его таким же (без белого пространства вокруг краев и выреза или выреза))

введите описание изображения здесь

Затем у вас есть изображение, с которым вы действительно можете работать.

В противном случае PURE CSS/JAVASCRIPT

ПРИМЕЧАНИЕ. Я не занимаюсь 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);
    }
<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

Образец, который вы отправили в ответ, может оказаться не лучшим для использования при создании фрейма. Вы должны получить 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 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>

Ответ 3

Я много пробовал создавать фрейм с помощью одного изображения через php, но не нашел никакого решения в php.

С помощью двух ответов (ответ Lucky Soni и ответ ScottS) я создал script для полного заполнения моего требования (спасибо им обоим).

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

Теперь я могу создать правильный кадр из любого типа изображения

Ответ 4

<?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

Ответ 5

Я смотрю ваше решение, это достаточно хорошо. Но я заметил несколько вещей, когда я пытался увеличить высоту и ширину, это не дало соответствующего результата.

Я попытался решить эту проблему, используя разные размеры изображения.

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

Надеюсь, это будет полезно для вас