How to upload multiple images after preview in laravel using cropper js

You can upload multiple images after preview in laravel using cropper js. Cropper js is a third party plugin that helps you crop images and after that, you can generate a URL and upload in laravel with comma-separated in the table column in laravel

Answers 1
  • Crop multiple images using cropper js and upload in laravel

    //Create routes in web.php
    //routes\web.php</p>
    Route::get('/cropper-js', function(){
        return view('cropper');
    });
    Route::post('/upload-images', '[email protected]');
    
    //Create controller
    php artisan make:controller CropperController
    
    //app\Http\Controllers\CropperController.php
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use App\Models\Image;
    use Illuminate\Support\Facades\Session;
    class CropperController extends Controller
    {
        //
    
        public function uploadImages(Request $request){
    
            $data = [];
    
            if($request->filled('image_data_url')){
                $imageDataURL = $request->image_data_url;
                $ImageDataURLArray = explode("img_url",$imageDataURL, -1);
    
                $images = array();
                foreach($ImageDataURLArray as $key => $image){
                    $image = str_replace('data:image/jpeg;base64,', '', $image);
                    $image = str_replace(' ', '+', $image);
                    $imageName = time().'_post_'.uniqid().'.jpeg';
                    $path = \File::put(storage_path('app/public/post'). '/' . $imageName, base64_decode($image));
                    $images[$key] = $imageName;
                }
    
                $images = implode(",",$images);
                //Comma seprated images in database column
                $data['images'] = $images;
            }
    
    
            $image = Image::create($data);
    
            if($image){
                
                Session::flash('message', 'Images uploaded successfully !');
                Session::flash('alert-class', 'alert-success');
                return view('cropper')->with('data', $image);
                //return redirect()->back()->with(['data' => $image]);
            }
    
            Session::flash('message', 'Error while uploading images !');
            Session::flash('alert-class', 'alert-danger');
            return redirect()->back();
        }
    }
    
    
    //Create view file with cropper.blade.php in resources/views directory
    //resources\views\cropper.blade.php
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Crop multiple images with cropper js</title>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" />
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
        <style>
        .g-height-50 {
            height: 50px;
        }
    
        .g-width-50 {
            width: 50px !important;
        }
    
        @media (min-width: 0){
            .g-pa-30 {
                padding: 2.14286rem !important;
            }
        }
    
        .g-bg-secondary {
            background-color: #fafafa !important;
        }
    
        .u-shadow-v18 {
            box-shadow: 0 5px 10px -6px rgba(0, 0, 0, 0.15);
        }
    
        .g-color-gray-dark-v4 {
            color: #777 !important;
        }
    
        .g-font-size-12 {
            font-size: 0.85714rem !important;
        }
    
        .media-comment {
            margin-top:20px
        }
        .singleImageCanvasContainer{
            overflow: hidden;
            height: 200px;
            width: 30%;
            display: inline-block;
            position: relative;
            padding-right: 0px;
            margin-right: 15px;
            border: 2px solid #dfdfdf;
            margin-bottom: 10px;
            padding: 4px;
            border-radius: .25rem;
        }
    
        .singleImageCanvasContainer .singleImageCanvasCloseBtn{
            position: absolute;
            right: 0;
        }
        .singleImageCanvasContainer .singleImageCanvas{
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
    </style>
    <link rel='stylesheet' type='text/css' property='stylesheet' href='//localhost:8000/_debugbar/assets/stylesheets?v=1644344552&theme=auto'><script src='//localhost:8000/_debugbar/assets/javascript?v=1644344552'></script><script>jQuery.noConflict(true);</script>
    <script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style'), rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx = /\bsf-dump-\d+-ref[012]\w+\b/, keyHint = 0 <= navigator.platform.toUpperCase().indexOf('MAC') ? 'Cmd' : 'Ctrl', addEventListener = function (e, n, cb) { e.addEventListener(n, cb, false); }; refStyle.innerHTML = '.phpdebugbar pre.sf-dump .sf-dump-compact, .sf-dump-str-collapse .sf-dump-str-collapse, .sf-dump-str-expand .sf-dump-str-expand { display: none; }'; (doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); refStyle = doc.createElement('style'); (doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); if (!doc.addEventListener) { addEventListener = function (element, eventName, callback) { element.attachEvent('on' + eventName, function (e) { e.preventDefault = function () {e.returnValue = false;}; e.target = e.srcElement; callback(e); }); }; } function toggle(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass; if (/\bsf-dump-compact\b/.test(oldClass)) { arrow = '▼'; newClass = 'sf-dump-expanded'; } else if (/\bsf-dump-expanded\b/.test(oldClass)) { arrow = '▶'; newClass = 'sf-dump-compact'; } else { return false; } if (doc.createEvent && s.dispatchEvent) { var event = doc.createEvent('Event'); event.initEvent('sf-dump-expanded' === newClass ? 'sfbeforedumpexpand' : 'sfbeforedumpcollapse', true, false); s.dispatchEvent(event); } a.lastChild.innerHTML = arrow; s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass); if (recursive) { try { a = s.querySelectorAll('.'+oldClass); for (s = 0; s < a.length; ++s) { if (-1 == a[s].className.indexOf(newClass)) { a[s].className = newClass; a[s].previousSibling.lastChild.innerHTML = arrow; } } } catch (e) { } } return true; }; function collapse(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-expanded\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function expand(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-compact\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function collapseAll(root) { var a = root.querySelector('a.sf-dump-toggle'); if (a) { collapse(a, true); expand(a); return true; } return false; } function reveal(node) { var previous, parents = []; while ((node = node.parentNode || {}) && (previous = node.previousSibling) && 'A' === previous.tagName) { parents.push(previous); } if (0 !== parents.length) { parents.forEach(function (parent) { expand(parent); }); return true; } return false; } function highlight(root, activeNode, nodes) { resetHighlightedNodes(root); Array.from(nodes||[]).forEach(function (node) { if (!/\bsf-dump-highlight\b/.test(node.className)) { node.className = node.className + ' sf-dump-highlight'; } }); if (!/\bsf-dump-highlight-active\b/.test(activeNode.className)) { activeNode.className = activeNode.className + ' sf-dump-highlight-active'; } } function resetHighlightedNodes(root) { Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) { strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, ''); strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, ''); }); } return function (root, x) { root = doc.getElementById(root); var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'), options = {"maxDepth":1,"maxStringLength":160,"fileLinkFormat":false}, elt = root.getElementsByTagName('A'), len = elt.length, i = 0, s, h, t = []; while (i < len) t.push(elt[i++]); for (i in x) { options[i] = x[i]; } function a(e, f) { addEventListener(root, e, function (e, n) { if ('A' == e.target.tagName) { f(e.target, e); } else if ('A' == e.target.parentNode.tagName) { f(e.target.parentNode, e); } else { n = /\bsf-dump-ellipsis\b/.test(e.target.className) ? e.target.parentNode : e.target; if ((n = n.nextElementSibling) && 'A' == n.tagName) { if (!/\bsf-dump-toggle\b/.test(n.className)) { n = n.nextElementSibling || n; } f(n, e, true); } } }); }; function isCtrlKey(e) { return e.ctrlKey || e.metaKey; } function xpathString(str) { var parts = str.match(/[^'"]+|['"]/g).map(function (part) { if ("'" == part) { return '"\'"'; } if ('"' == part) { return "'\"'"; } return "'" + part + "'"; }); return "concat(" + parts.join(",") + ", '')"; } function xpathHasClass(className) { return "contains(concat(' ', normalize-space(@class), ' '), ' " + className +" ')"; } addEventListener(root, 'mouseover', function (e) { if ('' != refStyle.innerHTML) { refStyle.innerHTML = ''; } }); a('mouseover', function (a, e, c) { if (c) { e.target.style.cursor = "pointer"; } else if (a = idRx.exec(a.className)) { try { refStyle.innerHTML = '.phpdebugbar pre.sf-dump .'+a[0]+'{background-color: #B729D9; color: #FFF !important; border-radius: 2px}'; } catch (e) { } } }); a('click', function (a, e, c) { if (/\bsf-dump-toggle\b/.test(a.className)) { e.preventDefault(); if (!toggle(a, isCtrlKey(e))) { var r = doc.getElementById(a.getAttribute('href').substr(1)), s = r.previousSibling, f = r.parentNode, t = a.parentNode; t.replaceChild(r, a); f.replaceChild(a, s); t.insertBefore(s, r); f = f.firstChild.nodeValue.match(indentRx); t = t.firstChild.nodeValue.match(indentRx); if (f && t && f[0] !== t[0]) { r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]); } if (/\bsf-dump-compact\b/.test(r.className)) { toggle(s, isCtrlKey(e)); } } if (c) { } else if (doc.getSelection) { try { doc.getSelection().removeAllRanges(); } catch (e) { doc.getSelection().empty(); } } else { doc.selection.empty(); } } else if (/\bsf-dump-str-toggle\b/.test(a.className)) { e.preventDefault(); e = a.parentNode.parentNode; e.className = e.className.replace(/\bsf-dump-str-(expand|collapse)\b/, a.parentNode.className); } }); elt = root.getElementsByTagName('SAMP'); len = elt.length; i = 0; while (i < len) t.push(elt[i++]); len = t.length; for (i = 0; i < len; ++i) { elt = t[i]; if ('SAMP' == elt.tagName) { a = elt.previousSibling || {}; if ('A' != a.tagName) { a = doc.createElement('A'); a.className = 'sf-dump-ref'; elt.parentNode.insertBefore(a, elt); } else { a.innerHTML += ' '; } a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children'; a.innerHTML += elt.className == 'sf-dump-compact' ? '<span>▶</span>' : '<span>▼</span>'; a.className += ' sf-dump-toggle'; x = 1; if ('sf-dump' != elt.parentNode.className) { x += elt.parentNode.getAttribute('data-depth')/1; } } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) { a = a.substr(1); elt.className += ' '+a; if (/[\[{]$/.test(elt.previousSibling.nodeValue)) { a = a != elt.nextSibling.id && doc.getElementById(a); try { s = a.nextSibling; elt.appendChild(a); s.parentNode.insertBefore(a, s); if (/^[@#]/.test(elt.innerHTML)) { elt.innerHTML += ' <span>▶</span>'; } else { elt.innerHTML = '<span>▶</span>'; elt.className = 'sf-dump-ref'; } elt.className += ' sf-dump-toggle'; } catch (e) { if ('&' == elt.innerHTML.charAt(0)) { elt.innerHTML = '…'; elt.className = 'sf-dump-ref'; } } } } } if (doc.evaluate && Array.from && root.children.length > 1) { root.setAttribute('tabindex', 0); SearchState = function () { this.nodes = []; this.idx = 0; }; SearchState.prototype = { next: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0; return this.current(); }, previous: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1); return this.current(); }, isEmpty: function () { return 0 === this.count(); }, current: function () { if (this.isEmpty()) { return null; } return this.nodes[this.idx]; }, reset: function () { this.nodes = []; this.idx = 0; }, count: function () { return this.nodes.length; }, }; function showCurrent(state) { var currentNode = state.current(), currentRect, searchRect; if (currentNode) { reveal(currentNode); highlight(root, currentNode, state.nodes); if ('scrollIntoView' in currentNode) { currentNode.scrollIntoView(true); currentRect = currentNode.getBoundingClientRect(); searchRect = search.getBoundingClientRect(); if (currentRect.top < (searchRect.top + searchRect.height)) { window.scrollBy(0, -(searchRect.top + searchRect.height + 5)); } } } counter.textContent = (state.isEmpty() ? 0 : state.idx + 1) + ' of ' + state.count(); } var search = doc.createElement('div'); search.className = 'sf-dump-search-wrapper sf-dump-search-hidden'; search.innerHTML = ' <input type="text" class="sf-dump-search-input"> <span class="sf-dump-search-count">0 of 0<\/span> <button type="button" class="sf-dump-search-input-previous" tabindex="-1"> <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1683 1331l-166 165q-19 19-45 19t-45-19L896 965l-531 531q-19 19-45 19t-45-19l-166-165q-19-19-19-45.5t19-45.5l742-741q19-19 45-19t45 19l742 741q19 19 19 45.5t-19 45.5z"\/><\/svg> <\/button> <button type="button" class="sf-dump-search-input-next" tabindex="-1"> <svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1683 808l-742 741q-19 19-45 19t-45-19L109 808q-19-19-19-45.5t19-45.5l166-165q19-19 45-19t45 19l531 531 531-531q19-19 45-19t45 19l166 165q19 19 19 45.5t-19 45.5z"\/><\/svg> <\/button> '; root.insertBefore(search, root.firstChild); var state = new SearchState(); var searchInput = search.querySelector('.sf-dump-search-input'); var counter = search.querySelector('.sf-dump-search-count'); var searchInputTimer = 0; var previousSearchQuery = ''; addEventListener(searchInput, 'keyup', function (e) { var searchQuery = e.target.value; /* Don't perform anything if the pressed key didn't change the query */ if (searchQuery === previousSearchQuery) { return; } previousSearchQuery = searchQuery; clearTimeout(searchInputTimer); searchInputTimer = setTimeout(function () { state.reset(); collapseAll(root); resetHighlightedNodes(root); if ('' === searchQuery) { counter.textContent = '0 of 0'; return; } var classMatches = [ "sf-dump-str", "sf-dump-key", "sf-dump-public", "sf-dump-protected", "sf-dump-private", ].map(xpathHasClass).join(' or '); var xpathResult = doc.evaluate('.//span[' + classMatches + '][contains(translate(child::text(), ' + xpathString(searchQuery.toUpperCase()) + ', ' + xpathString(searchQuery.toLowerCase()) + '), ' + xpathString(searchQuery.toLowerCase()) + ')]', root, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); while (node = xpathResult.iterateNext()) state.nodes.push(node); showCurrent(state); }, 400); }); Array.from(search.querySelectorAll('.sf-dump-search-input-next, .sf-dump-search-input-previous')).forEach(function (btn) { addEventListener(btn, 'click', function (e) { e.preventDefault(); -1 !== e.target.className.indexOf('next') ? state.next() : state.previous(); searchInput.focus(); collapseAll(root); showCurrent(state); }) }); addEventListener(root, 'keydown', function (e) { var isSearchActive = !/\bsf-dump-search-hidden\b/.test(search.className); if ((114 === e.keyCode && !isSearchActive) || (isCtrlKey(e) && 70 === e.keyCode)) { /* F3 or CMD/CTRL + F */ if (70 === e.keyCode && document.activeElement === searchInput) { /* * If CMD/CTRL + F is hit while having focus on search input, * the user probably meant to trigger browser search instead. * Let the browser execute its behavior: */ return; } e.preventDefault(); search.className = search.className.replace(/\bsf-dump-search-hidden\b/, ''); searchInput.focus(); } else if (isSearchActive) { if (27 === e.keyCode) { /* ESC key */ search.className += ' sf-dump-search-hidden'; e.preventDefault(); resetHighlightedNodes(root); searchInput.value = ''; } else if ( (isCtrlKey(e) && 71 === e.keyCode) /* CMD/CTRL + G */ || 13 === e.keyCode /* Enter */ || 114 === e.keyCode /* F3 */ ) { e.preventDefault(); e.shiftKey ? state.previous() : state.next(); collapseAll(root); showCurrent(state); } } }); } if (0 >= options.maxStringLength) { return; } try { elt = root.querySelectorAll('.sf-dump-str'); len = elt.length; i = 0; t = []; while (i < len) t.push(elt[i++]); len = t.length; for (i = 0; i < len; ++i) { elt = t[i]; s = elt.innerText || elt.textContent; x = s.length - options.maxStringLength; if (0 < x) { h = elt.innerHTML; elt[elt.innerText ? 'innerText' : 'textContent'] = s.substring(0, options.maxStringLength); elt.className += ' sf-dump-str-collapse'; elt.innerHTML = '<span class=sf-dump-str-collapse>'+h+'<a class="sf-dump-ref sf-dump-str-toggle" title="Collapse"> ◀</a></span>'+ '<span class=sf-dump-str-expand>'+elt.innerHTML+'<a class="sf-dump-ref sf-dump-str-toggle" title="'+x+' remaining characters"> ▶</a></span>'; } } } catch (e) { } }; })(document); </script><style> .phpdebugbar pre.sf-dump { display: block; white-space: pre; padding: 5px; overflow: initial !important; } .phpdebugbar pre.sf-dump:after { content: ""; visibility: hidden; display: block; height: 0; clear: both; } .phpdebugbar pre.sf-dump span { display: inline; } .phpdebugbar pre.sf-dump a { text-decoration: none; cursor: pointer; border: 0; outline: none; color: inherit; } .phpdebugbar pre.sf-dump img { max-width: 50em; max-height: 50em; margin: .5em 0 0 0; padding: 0; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAHUlEQVQY02O8zAABilCaiQEN0EeA8QuUcX9g3QEAAjcC5piyhyEAAAAASUVORK5CYII=) #D3D3D3; } .phpdebugbar pre.sf-dump .sf-dump-ellipsis { display: inline-block; overflow: visible; text-overflow: ellipsis; max-width: 5em; white-space: nowrap; overflow: hidden; vertical-align: top; } .phpdebugbar pre.sf-dump .sf-dump-ellipsis+.sf-dump-ellipsis { max-width: none; } .phpdebugbar pre.sf-dump code { display:inline; padding:0; background:none; } .sf-dump-public.sf-dump-highlight, .sf-dump-protected.sf-dump-highlight, .sf-dump-private.sf-dump-highlight, .sf-dump-str.sf-dump-highlight, .sf-dump-key.sf-dump-highlight { background: rgba(111, 172, 204, 0.3); border: 1px solid #7DA0B1; border-radius: 3px; } .sf-dump-public.sf-dump-highlight-active, .sf-dump-protected.sf-dump-highlight-active, .sf-dump-private.sf-dump-highlight-active, .sf-dump-str.sf-dump-highlight-active, .sf-dump-key.sf-dump-highlight-active { background: rgba(253, 175, 0, 0.4); border: 1px solid #ffa500; border-radius: 3px; } .phpdebugbar pre.sf-dump .sf-dump-search-hidden { display: none !important; } .phpdebugbar pre.sf-dump .sf-dump-search-wrapper { font-size: 0; white-space: nowrap; margin-bottom: 5px; display: flex; position: -webkit-sticky; position: sticky; top: 5px; } .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > * { vertical-align: top; box-sizing: border-box; height: 21px; font-weight: normal; border-radius: 0; background: #FFF; color: #757575; border: 1px solid #BBB; } .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > input.sf-dump-search-input { padding: 3px; height: 21px; font-size: 12px; border-right: none; border-top-left-radius: 3px; border-bottom-left-radius: 3px; color: #000; min-width: 15px; width: 100%; } .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next, .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous { background: #F2F2F2; outline: none; border-left: none; font-size: 0; line-height: 0; } .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-next > svg, .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-input-previous > svg { pointer-events: none; width: 12px; height: 12px; } .phpdebugbar pre.sf-dump .sf-dump-search-wrapper > .sf-dump-search-count { display: inline-block; padding: 0 5px; margin: 0; border-left: none; line-height: 21px; font-size: 12px; }.phpdebugbar pre.sf-dump, .phpdebugbar pre.sf-dump .sf-dump-default{word-wrap: break-word; white-space: pre-wrap; word-break: normal}.phpdebugbar pre.sf-dump .sf-dump-num{font-weight:bold; color:#1299DA}.phpdebugbar pre.sf-dump .sf-dump-const{font-weight:bold}.phpdebugbar pre.sf-dump .sf-dump-str{font-weight:bold; color:#3A9B26}.phpdebugbar pre.sf-dump .sf-dump-note{color:#1299DA}.phpdebugbar pre.sf-dump .sf-dump-ref{color:#7B7B7B}.phpdebugbar pre.sf-dump .sf-dump-public{color:#000000}.phpdebugbar pre.sf-dump .sf-dump-protected{color:#000000}.phpdebugbar pre.sf-dump .sf-dump-private{color:#000000}.phpdebugbar pre.sf-dump .sf-dump-meta{color:#B729D9}.phpdebugbar pre.sf-dump .sf-dump-key{color:#3A9B26}.phpdebugbar pre.sf-dump .sf-dump-index{color:#1299DA}.phpdebugbar pre.sf-dump .sf-dump-ellipsis{color:#A0A000}.phpdebugbar pre.sf-dump .sf-dump-ns{user-select:none;}.phpdebugbar pre.sf-dump .sf-dump-ellipsis-note{color:#1299DA}</style>
    </head>
    <body>
    
    
    <!-- code by w3codegenerator.com -->
    <div class="container m-5">
        <div class="row">
            <div class="col-md-12">
                <input type="file" name="file" id="file" accept="image/*" multiple />
            </div>
    
            @if(Session::has('message'))
            <div class="col-md-12">
                <div class="alert {{ Session::get('alert-class', 'alert-info') }} alert-dismissible fade show mt-5">
                    {{ Session::get('message') }}
                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
            </div>
            @endif
    
            @if(isset($data))
                @php $images = explode(",", $data->images)  @endphp
                @foreach($images as $image)
                <div class="col-md-4">
                    <img src="{{ asset('storage/post/'.$image) }}" alt="..."/>
                </div>
                @endforeach
            @endif
        </div>
    </div>
    
    <div class="modal" id="cropperModal">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">Upload Images</h4>
                   <button type="button" class="close" data-dismiss="modal">&times;</button>
                </div>
                <form action="/upload-images" method="POST" enctype="multipart/form-data">
                @csrf
                <input type="hidden" id="post_img_data" name="image_data_url">
                <div class="modal-body p-4">
                    <div class="img-preview"></div>
                    <div id="galleryImages"></div>
                    <div id="cropper">
                        <canvas id="cropperImg" width="0" height="0"></canvas>
                        <button type="button" class="cropImageBtn btn btn-danger" style="display:none;" id="cropImageBtn">Crop</button>
                    </div>
                    <div id="imageValidate" class="text-danger"></div>
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn btn-primary">Upload</button>
                </div>
                </form>
            </div>
        </div>
    </div>
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.5/cropper.min.js" integrity="sha512-E4KfIuQAc9ZX6zW1IUJROqxrBqJXPuEcDKP6XesMdu2OV4LW7pj8+gkkyx2y646xEV7yxocPbaTtk2LQIJewXw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.5/cropper.min.css" integrity="sha512-Aix44jXZerxlqPbbSLJ03lEsUch9H/CmnNfWxShD6vJBbboR+rPdDXmKN+/QjISWT80D4wMjtM4Kx7+xkLVywQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    
    <script>
        $(document).ready(function(){
            $("body").on("change", "#file", function(e){
                $('.singleImageCanvasContainer').remove();
                $('#post_img_data').val('');
            });
        })
    </script>
    <script>
    
        //Multiple image cropper and preview on creating post
        var c;
        var galleryImagesContainer = document.getElementById('galleryImages');
        var imageCropFileInput = document.getElementById('file');
        var cropperImageInitCanvas = document.getElementById('cropperImg');
        var cropImageButton = document.getElementById('cropImageBtn');
        // Crop Function On change
        function imagesPreview(input) {
            var cropper;
            //cropImageButton.className = 'show';
            var img = [];
            if (input.files.length) {
                var i = 0;
                var index = 0;
                for (let singleFile of input.files) {
                    var reader = new FileReader();
                    reader.onload = function(event) {
                        var blobUrl = event.target.result;
                        img.push(new Image());
                        img[i].onload = function(e) {
                            // Canvas Container
                            var singleCanvasImageContainer = document.createElement('div');
                            singleCanvasImageContainer.id = 'singleImageCanvasContainer'+index;
                            singleCanvasImageContainer.className = 'singleImageCanvasContainer';
                            // Canvas Close Btn
                            var singleCanvasImageCloseBtn = document.createElement('button');
                            var singleCanvasImageCloseBtnText = document.createTextNode('X');
                            // var singleCanvasImageCloseBtnText = document.createElement('i');
                            // singleCanvasImageCloseBtnText.className = 'fa fa-times';
                            singleCanvasImageCloseBtn.id = 'singleImageCanvasCloseBtn'+index;
                            singleCanvasImageCloseBtn.className = 'singleImageCanvasCloseBtn';
                            singleCanvasImageCloseBtn.classList.add("btn", "btn-sm");
                            singleCanvasImageCloseBtn.onclick = function() { 
                                removeSingleCanvas(this) 
                            };
                            singleCanvasImageCloseBtn.appendChild(singleCanvasImageCloseBtnText);
                            singleCanvasImageContainer.appendChild(singleCanvasImageCloseBtn);
                            // Image Canvas
                            var canvas = document.createElement('canvas');
                            canvas.id = 'imageCanvas'+index;
                            canvas.className = 'imageCanvas singleImageCanvas';
                            canvas.width = e.currentTarget.width;
                            canvas.height = e.currentTarget.height;
                            canvas.onclick = function() { cropInit(canvas.id); };
                            singleCanvasImageContainer.appendChild(canvas)
                            // Canvas Context
                            var ctx = canvas.getContext('2d');
                            ctx.drawImage(e.currentTarget,0,0);
                            // galleryImagesContainer.append(canvas);
                            galleryImagesContainer.appendChild(singleCanvasImageContainer);
                            // while (document.querySelectorAll('.singleImageCanvas').length == input.files.length) {
                            //     var allCanvasImages = document.querySelectorAll('.singleImageCanvas')[0].getAttribute('id');
                            //     console.log(allCanvasImages);
                            //     //commented by sam
                            //     //cropInit(allCanvasImages);
                            //     break;
                            // };
                            urlConversion();
                            index++;
                    };
                        img[i].src = blobUrl;
                        i++;
                    }
                    reader.readAsDataURL(singleFile);
                }
            }
        }
    
        imageCropFileInput.addEventListener("change", function(event){
            
            $('#cropperModal').modal('show');
            var mediaValidation = validatePostMedia(event.target.files);
            if(!mediaValidation){
                var $el = $('#file');
                $el.wrap('<form>').closest('form').get(0).reset();
                $el.unwrap();
                return false;
            }
    
            $('#mediaPreview').empty();
            $('.singleImageCanvasContainer').remove();
            if(cropperImageInitCanvas.cropper){
                cropperImageInitCanvas.cropper.destroy();
                cropperImageInitCanvas.width = 0;
                cropperImageInitCanvas.height = 0;
                cropImageButton.style.display = 'none';
            }
            imagesPreview(event.target);
        });
        // Initialize Cropper
        function cropInit(selector) {
            c = document.getElementById(selector);
            
            if(cropperImageInitCanvas.cropper){
                cropperImageInitCanvas.cropper.destroy();
            }
            var allCloseButtons = document.querySelectorAll('.singleImageCanvasCloseBtn');
            for (let element of allCloseButtons) {
                element.style.display = 'block';
            }
            c.previousSibling.style.display = 'none';
            // c.id = croppedImg;
            var ctx=c.getContext('2d');
            var imgData=ctx.getImageData(0, 0, c.width, c.height);
            var image = cropperImageInitCanvas;
            image.width = c.width;
            image.height = c.height;
            var ctx = image.getContext('2d');
            ctx.putImageData(imgData,0,0);
    
            cropper = new Cropper(image, {
                aspectRatio: 16/9,
    			viewMode: 4,
                preview: '.img-preview',
                crop: function(event) {
                    cropImageButton.style.display = 'block';
                }
            });
    
        }
        
        function image_crop() {
            if(cropperImageInitCanvas.cropper){
                var cropcanvas = cropperImageInitCanvas.cropper.getCroppedCanvas({
                        width: 250, height: 250
                    });
                // document.getElementById('cropImages').appendChild(cropcanvas);
                var ctx=cropcanvas.getContext('2d');
                var imgData=ctx.getImageData(0, 0, cropcanvas.width, cropcanvas.height);
                // var image = document.getElementById(c);
                c.width = cropcanvas.width;
                c.height = cropcanvas.height;
                var ctx = c.getContext('2d');
                ctx.putImageData(imgData,0,0);
                cropperImageInitCanvas.cropper.destroy();
                cropperImageInitCanvas.width = 0;
                cropperImageInitCanvas.height = 0;
                cropImageButton.style.display = 'none';
                var allCloseButtons = document.querySelectorAll('.singleImageCanvasCloseBtn');
                for (let element of allCloseButtons) {
                    element.style.display = 'block';
                }
                urlConversion();
            } else {
                alert('Please select any Image you want to crop');
            }
        }
        cropImageButton.addEventListener("click", function(){
            image_crop();
        });
        // Image Close/Remove
        function removeSingleCanvas(selector) {
            selector.parentNode.remove();
            urlConversion();
        }
        
        function urlConversion() {
            var allImageCanvas = document.querySelectorAll('.singleImageCanvas');
            var convertedUrl = '';
            canvasLength = allImageCanvas.length;
            for (let element of allImageCanvas) {
                convertedUrl += element.toDataURL('image/jpeg');
                convertedUrl += 'img_url';
            }
            document.getElementById('post_img_data').value = convertedUrl;
        }
    </script>
    <script>
        function validatePostMedia(files){
    
            $('#imageValidate').empty();
            let err = 0;
            let ResponseTxt = '';
            if(files.length > 10){
                err += 1;
                ResponseTxt += '<p> You can select maximum 10 files. </p>';
            }
            $(files).each(function(index, file) {
                if(file.size > 1048576){
                    err +=  1;
                    ResponseTxt += 'File : '+file.name + ' is greater than 1MB';
                }
            });
    
            if(err > 0){
                $('#imageValidate').html(ResponseTxt);
                return false;
            }
            return true;
            
        }
    </script>
    </body>
    </html>
    
    //php artisan make:model Image -m
    //database\migrations\2021_08_12_044218_create_images_table.php
    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->string('images', 500);
            $table->timestamps();
        });
    }
    
    php artisan migrate
    
    //This will create a table (images) structure with column images in the database.
    //app\Models\Image.php
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Image extends Model
    {
        use HasFactory;
    
        protected $fillable = ['images'];
    }
    
    0

    create web routes in the web.php file. Create model, migration using artisan command after that create table structure using the migration file and run php artisan migrate command to create the table in the database. Create the view file with cropper.blade.php name. To upload files in the directory create post folder inside the storage/app/public directory to upload images in the post directory.

  • Back to code snippet queries related laravel