Scale down images effectively without losing aspect ratio or quality in php

我的未来我决定 提交于 2019-12-23 03:19:37

问题


I am about launch my biggest dream website(my first one), but have some unresolved issues. I am a complete newbie to coding and highly rely on plugins and tutorials to get stuff done. Now, I am facing problems in handling images and I have tried a lot of options to solve these issues, but not found any perfect solution. I have a feature where users can create their own profile, upload profile pic and a cover pic, re-position it and save it(somewhat like facebook). And also they can update their statuses where they can post multiple images(up to 5).

My requirements are:

  1. While re-positioning and saving the cover pic, I am saving the 'x' and 'y' position of the new position and cropping the image to save it separately. Problem here is, the cropping is done to fit the height and width of the container div of the image.(say the height of the container is 250px and width is 325px, image is cropped to fit that div). Since my container is responsive, the height and width vary in different screen sizes, and so does my cropped image. On a small screen, the image is cropped to 100px * 180px, which is a disaster. I want to know the effective way to deal with this so that the image is consistent everywhere.
  2. In multiple uploads, everything seemed to work fine until I opened the Network tab in my chrome developer tools. One page had 26 images and the page size was a whooping 11.8mb. I used GD library to scale down my images, but now if I try to further resize them to reduce file size, the quality is lost and images become blurry. I am planning to use ImageMagick, but have no idea whether it will serve my purpose. I don't want any of my images to cross 50kb - 60kb but still maintain considerable amount quality. Can I achieve this !

Here is the code I use for Cover pic

HTML

<div class="drag-banner">
        <!--Container div for Cropped and repositioned image-->
    <div class="banner-wrapper"> 
        <!--Dropdown menu for Options-->
        <div class="dropdown upload-banner">
            <div class="dropdown-toggle cam-wrap" type="button" data-toggle="dropdown" >
                <i class="fa fa-camera"></i>
            </div>
            <ul class="dropdown-menu" role="menu">

                <li role="presentation" id="" class="uplbBtn">
                    <a role="menuitem" tabindex="-1" class="type-file">
                        <form class="banrPosition-form" method="post" enctype="multipart/form-data">
                            <label class="label-file" for="uploadImage">
                                <i class="fa fa-upload"></i>Upload Cover
                                <input type="file" class="btn-file" name="uploadImg" id="uploadImage">
                            </label>
                            <input type="hidden" class="banrPosition" name="pos" id="pos" value="0">
                        </form>
                    </a>
                </li>
                <li role="presentation"><a role="menuitem" tabindex="-1" id="repstnBnr"><i class="fa fa-arrows"></i>Reposition Cover</a></li>
            </ul>
        </div>
        <!--Cropped Image-->
        <img class="img-responsive bannr-img" id="cropped" src="<?php echo $croppedUrl; ?>">
    </div>
<!--Container div for Original uncropped image-->
    <div class="banner-resize-wrapper">
        <img class="img-responsive banner-img" id="uncropped" src="">
    </div>
<!--Drag and reposition instruction text-->
    <div class="drag">
        <div class="txt"><i class="fa fa-arrows"></i> Drag to reposition banner</div>
    </div>
<!--Div shown during ajax submit-->
    <div class="ajxFrmDiv"><div class="txt"></div></div>
 </div>

    <button id="savRpstn" class="btn btn-primary btn-xs savRpstn marg-all-sm">Save Position</button>  
    <button id="cnclRpstn" class="btn btn-default btn-xs cnclRpstn marg-all-sm">Cancel</button>

CSS

.drag-banner {margin: 0 auto;padding: 0;position: relative;height:275px;} /*Main Container*/

.banner-wrapper {display: block;} /*Original Image Wrapper*/
.banner-resize-wrapper {display: none;} /*Original Image Wrapper*/

.banner-wrapper,.banner-resize-wrapper{width: 100%;position:relative;overflow:hidden;height:100%;}

.banner-wrapper img.banner-img{width: 100%;max-height: 100%;}
.banner-resize-wrapper img.banner-img {position: absolute;width: 100%;min-height:100%;cursor:s-resize;}

.cam-wrap{border-radius:50%;background: transparent;padding: 8px;border:2px solid transparent;}

.banner-wrapper:hover > .upload-banner > .cam-wrap, .upload-banner.open .cam-wrap
{border-radius:50%;background: rgba(0,0,0,0.5);padding: 8px;border:3px solid #ccc;}
.banner-wrapper:hover > .upload-banner > .cam-wrap > .fa-camera, .upload-banner.open .cam-wrap .fa-camera{
    font-size: 120%; 
    -o-transition: all 0.085s;
    -moz-transition: all 0.085s;
    -webkit-transition: all 0.085s;
    transition: all 0.085s;
}

.upload-banner{
    cursor: pointer;
    position: absolute;
    z-index: 10;
    top: 10px;
    left: 10px;
}

.btn-file{padding:0;}
.dropdown-menu .label-file{width:100%;height:100%;padding:5px 15px;} /*Padding to match with dropdown-menu>li>a padding*/
.label-file{cursor: pointer;} 
.label-file .btn-file {
    position: fixed;
    top: -1000px;
    width: 100%;
    height: 100%;
    outline: none;
    cursor: pointer !important;
}

.drag-banner .black-strip{padding: 0 10px;}

.drag{
    line-height: 26px;
    position: absolute;
    text-align: center;
    top: 40%;
    width: 100%;
    display: none;
}
.drag .txt{
    background-color: rgba(84, 97, 133, 0.5);
    -webkit-border-radius: 2px;
    -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, .12);
    color: #fff;
    display: inline;
    font-size: 13px;
    font-weight: 700;
    padding: 5px 10px;
}

.ajxFrmDiv{
    top: 0;
    left: 0;
    width: 100%;
    color: #000; 
    height: 100%;
    display: none;
    margin: 0 auto;
    font-size: 150%;
    font-weight: 700;
    position: absolute;
    z-index: 11000;
    background: rgba(255,255,255,0.75);
}
.ajxFrmDiv .txt{
    position: absolute;
    top: 40%;
    left: 35%; 
    align-items: center;
    display: -webkit-flex;  
    display: flex;
    -webkit-justify-content: center;   
    justify-content: center;
}

JS

$('body').on('click', '#savRpstn', function() {
    saveReposition();
});

function saveReposition() {

        x1 = $('.drag-banner').width(); //Container Width
        y1 = $('.drag-banner').height(); //Container Height
        y2 = $('.banner-resize-wrapper').find('img').height(); //Image Height

//The form is submitted here with the above values
}

PHP

//The width, height and position from top are sent like this
$from_top = abs($_POST['x1']);
$default_cover_width = $_POST['y1'];
$default_cover_height = $_POST['y2'];

$tb->cropThumb($default_cover_width, $default_cover_height, 0, $from_top);

//New Image is formed 
public function cropThumb($width, $height, $x, $y)
    {
        $oldw = $this->getWidth();
        $oldh = $this->getHeight();

        $this->handlethumb = imagecreatetruecolor($width, $height);

        return imagecopy($this->handlethumb, $this->handleimg, 0, 0, $x, $y, $width, $height);
    }

I'm sorry I am not able to recreate the issue anywhere, I don't know how JSFiddle works.

I have uploaded a .gif image on Imagur which shows the issue. I have illustrated how the image is cropped in 2 different screen sizes. Kindly take a look and help me in cropping and resizing these images efficiently

来源:https://stackoverflow.com/questions/29205440/scale-down-images-effectively-without-losing-aspect-ratio-or-quality-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!