Media: Fix admin image cropping calculations.
The admin image editor crop function introduced rounding errors by using a scaled image to calculate values. Fix uses the image at 100% scale for calculations. Also avoid recalculating selection when the selection position is changed, and prevent incorrect values after scaling or restoration. Previously committed in [58456] and reverted in [58571]. The revert was due to a misattributed test failure. Props Jossnaz, johnillo, shailu25, rachelbaker, sudipatel007, joedolson, kevin940726 , andrewserong, hmbashar. Fixes #32282. Built from https://develop.svn.wordpress.org/trunk@58915 git-svn-id: http://core.svn.wordpress.org/trunk@58311 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
ce2b9f1fb2
commit
a88967db6e
|
@ -735,10 +735,10 @@ function image_edit_apply_changes( $image, $changes ) {
|
||||||
$w = $size['width'];
|
$w = $size['width'];
|
||||||
$h = $size['height'];
|
$h = $size['height'];
|
||||||
|
|
||||||
$scale = 1 / _image_get_preview_ratio( $w, $h ); // Discard preview scaling.
|
$scale = isset( $sel->r ) ? $sel->r : 1 / _image_get_preview_ratio( $w, $h ); // Discard preview scaling.
|
||||||
$image->crop( (int) ( $sel->x * $scale ), (int) ( $sel->y * $scale ), (int) ( $sel->w * $scale ), (int) ( $sel->h * $scale ) );
|
$image->crop( (int) ( $sel->x * $scale ), (int) ( $sel->y * $scale ), (int) ( $sel->w * $scale ), (int) ( $sel->h * $scale ) );
|
||||||
} else {
|
} else {
|
||||||
$scale = 1 / _image_get_preview_ratio( imagesx( $image ), imagesy( $image ) ); // Discard preview scaling.
|
$scale = isset( $sel->r ) ? $sel->r : 1 / _image_get_preview_ratio( imagesx( $image ), imagesy( $image ) ); // Discard preview scaling.
|
||||||
$image = _crop_image_resource( $image, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale );
|
$image = _crop_image_resource( $image, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -143,17 +143,12 @@
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
init : function(postid) {
|
init : function(postid) {
|
||||||
var t = this, old = $('#image-editor-' + t.postid),
|
var t = this, old = $('#image-editor-' + t.postid);
|
||||||
x = t.intval( $('#imgedit-x-' + postid).val() ),
|
|
||||||
y = t.intval( $('#imgedit-y-' + postid).val() );
|
|
||||||
|
|
||||||
if ( t.postid !== postid && old.length ) {
|
if ( t.postid !== postid && old.length ) {
|
||||||
t.close(t.postid);
|
t.close(t.postid);
|
||||||
}
|
}
|
||||||
|
|
||||||
t.hold.w = t.hold.ow = x;
|
|
||||||
t.hold.h = t.hold.oh = y;
|
|
||||||
t.hold.xy_ratio = x / y;
|
|
||||||
t.hold.sizer = parseFloat( $('#imgedit-sizer-' + postid).val() );
|
t.hold.sizer = parseFloat( $('#imgedit-sizer-' + postid).val() );
|
||||||
t.postid = postid;
|
t.postid = postid;
|
||||||
$('#imgedit-response-' + postid).empty();
|
$('#imgedit-response-' + postid).empty();
|
||||||
|
@ -188,6 +183,29 @@
|
||||||
$( document ).on( 'image-editor-ui-ready', this.focusManager );
|
$( document ).on( 'image-editor-ui-ready', this.focusManager );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the image size and save it to memory.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @memberof imageEdit
|
||||||
|
*
|
||||||
|
* @param {number} postid The post ID.
|
||||||
|
*
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
calculateImgSize: function( postid ) {
|
||||||
|
var t = this,
|
||||||
|
x = t.intval( $( '#imgedit-x-' + postid ).val() ),
|
||||||
|
y = t.intval( $( '#imgedit-y-' + postid ).val() );
|
||||||
|
|
||||||
|
t.hold.w = t.hold.ow = x;
|
||||||
|
t.hold.h = t.hold.oh = y;
|
||||||
|
t.hold.xy_ratio = x / y;
|
||||||
|
t.hold.sizer = parseFloat( $( '#imgedit-sizer-' + postid ).val() );
|
||||||
|
t.currentCropSelection = null;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the wait/load icon in the editor.
|
* Toggles the wait/load icon in the editor.
|
||||||
*
|
*
|
||||||
|
@ -525,7 +543,7 @@
|
||||||
for ( n in history ) {
|
for ( n in history ) {
|
||||||
i = history[n];
|
i = history[n];
|
||||||
if ( i.hasOwnProperty('c') ) {
|
if ( i.hasOwnProperty('c') ) {
|
||||||
op[n] = { 'c': { 'x': i.c.x, 'y': i.c.y, 'w': i.c.w, 'h': i.c.h } };
|
op[n] = { 'c': { 'x': i.c.x, 'y': i.c.y, 'w': i.c.w, 'h': i.c.h, 'r': i.c.r } };
|
||||||
} else if ( i.hasOwnProperty('r') ) {
|
} else if ( i.hasOwnProperty('r') ) {
|
||||||
op[n] = { 'r': i.r.r };
|
op[n] = { 'r': i.r.r };
|
||||||
} else if ( i.hasOwnProperty('f') ) {
|
} else if ( i.hasOwnProperty('f') ) {
|
||||||
|
@ -860,6 +878,7 @@
|
||||||
if ( 'undefined' === typeof this.hold.sizer ) {
|
if ( 'undefined' === typeof this.hold.sizer ) {
|
||||||
this.init( postid );
|
this.init( postid );
|
||||||
}
|
}
|
||||||
|
this.calculateImgSize( postid );
|
||||||
|
|
||||||
this.initCrop(postid, img, parent);
|
this.initCrop(postid, img, parent);
|
||||||
this.setCropSelection( postid, { 'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0, 'width': img.innerWidth(), 'height': img.innerHeight() } );
|
this.setCropSelection( postid, { 'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0, 'width': img.innerWidth(), 'height': img.innerHeight() } );
|
||||||
|
@ -909,8 +928,6 @@
|
||||||
var t = this,
|
var t = this,
|
||||||
selW = $('#imgedit-sel-width-' + postid),
|
selW = $('#imgedit-sel-width-' + postid),
|
||||||
selH = $('#imgedit-sel-height-' + postid),
|
selH = $('#imgedit-sel-height-' + postid),
|
||||||
selX = $('#imgedit-start-x-' + postid),
|
|
||||||
selY = $('#imgedit-start-y-' + postid),
|
|
||||||
$image = $( image ),
|
$image = $( image ),
|
||||||
$img;
|
$img;
|
||||||
|
|
||||||
|
@ -945,13 +962,16 @@
|
||||||
*
|
*
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
parent.children().on( 'mousedown, touchstart', function(e){
|
parent.children().on( 'mousedown touchstart', function(e) {
|
||||||
var ratio = false, sel, defRatio;
|
var ratio = false,
|
||||||
|
sel = t.iasapi.getSelection(),
|
||||||
|
cx = t.intval( $( '#imgedit-crop-width-' + postid ).val() ),
|
||||||
|
cy = t.intval( $( '#imgedit-crop-height-' + postid ).val() );
|
||||||
|
|
||||||
if ( e.shiftKey ) {
|
if ( cx && cy ) {
|
||||||
sel = t.iasapi.getSelection();
|
ratio = t.getSelRatio( postid );
|
||||||
defRatio = t.getSelRatio(postid);
|
} else if ( e.shiftKey && sel && sel.width && sel.height ) {
|
||||||
ratio = ( sel && sel.width && sel.height ) ? sel.width + ':' + sel.height : defRatio;
|
ratio = sel.width + ':' + sel.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
t.iasapi.setOptions({
|
t.iasapi.setOptions({
|
||||||
|
@ -1000,11 +1020,17 @@
|
||||||
* @return {void}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
onSelectChange: function(img, c) {
|
onSelectChange: function(img, c) {
|
||||||
var sizer = imageEdit.hold.sizer;
|
var sizer = imageEdit.hold.sizer,
|
||||||
selW.val( imageEdit.round(c.width / sizer) );
|
oldSel = imageEdit.currentCropSelection;
|
||||||
selH.val( imageEdit.round(c.height / sizer) );
|
|
||||||
selX.val( imageEdit.round(c.x1 / sizer) );
|
if ( oldSel != null && oldSel.width == c.width && oldSel.height == c.height ) {
|
||||||
selY.val( imageEdit.round(c.y1 / sizer) );
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selW.val( Math.min( imageEdit.hold.w, imageEdit.round( c.width / sizer ) ) );
|
||||||
|
selH.val( Math.min( imageEdit.hold.h, imageEdit.round( c.height / sizer ) ) );
|
||||||
|
|
||||||
|
t.currentCropSelection = c;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -1022,7 +1048,11 @@
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
setCropSelection : function(postid, c) {
|
setCropSelection : function(postid, c) {
|
||||||
var sel;
|
var sel,
|
||||||
|
selW = $( '#imgedit-sel-width-' + postid ),
|
||||||
|
selH = $( '#imgedit-sel-height-' + postid ),
|
||||||
|
sizer = this.hold.sizer,
|
||||||
|
hold = this.hold;
|
||||||
|
|
||||||
c = c || 0;
|
c = c || 0;
|
||||||
|
|
||||||
|
@ -1037,7 +1067,15 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sel = { 'x': c.x1, 'y': c.y1, 'w': c.width, 'h': c.height };
|
// adjust the selection within the bounds of the image on 100% scale
|
||||||
|
var excessW = hold.w - ( Math.round( c.x1 / sizer ) + parseInt( selW.val() ) );
|
||||||
|
var excessH = hold.h - ( Math.round( c.y1 / sizer ) + parseInt( selH.val() ) );
|
||||||
|
var x = Math.round( c.x1 / sizer ) + Math.min( 0, excessW );
|
||||||
|
var y = Math.round( c.y1 / sizer ) + Math.min( 0, excessH );
|
||||||
|
|
||||||
|
// use 100% scaling to prevent rounding errors
|
||||||
|
sel = { 'r': 1, 'x': x, 'y': y, 'w': selW.val(), 'h': selH.val() };
|
||||||
|
|
||||||
this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 1);
|
this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 1);
|
||||||
$('#imgedit-selection-' + postid).val( JSON.stringify(sel) );
|
$('#imgedit-selection-' + postid).val( JSON.stringify(sel) );
|
||||||
},
|
},
|
||||||
|
@ -1165,6 +1203,11 @@
|
||||||
}
|
}
|
||||||
this.closePopup(t);
|
this.closePopup(t);
|
||||||
this.addStep({ 'r': { 'r': angle, 'fw': this.hold.h, 'fh': this.hold.w }}, postid, nonce);
|
this.addStep({ 'r': { 'r': angle, 'fw': this.hold.h, 'fh': this.hold.w }}, postid, nonce);
|
||||||
|
|
||||||
|
// Clear the selection fields after rotating.
|
||||||
|
$( '#imgedit-sel-width-' + postid ).val( '' );
|
||||||
|
$( '#imgedit-sel-height-' + postid ).val( '' );
|
||||||
|
this.currentCropSelection = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1187,6 +1230,11 @@
|
||||||
}
|
}
|
||||||
this.closePopup(t);
|
this.closePopup(t);
|
||||||
this.addStep({ 'f': { 'f': axis, 'fw': this.hold.w, 'fh': this.hold.h }}, postid, nonce);
|
this.addStep({ 'f': { 'f': axis, 'fw': this.hold.w, 'fh': this.hold.h }}, postid, nonce);
|
||||||
|
|
||||||
|
// Clear the selection fields after flipping.
|
||||||
|
$( '#imgedit-sel-width-' + postid ).val( '' );
|
||||||
|
$( '#imgedit-sel-height-' + postid ).val( '' );
|
||||||
|
this.currentCropSelection = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1219,10 +1267,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the selection fields after cropping.
|
// Clear the selection fields after cropping.
|
||||||
$('#imgedit-sel-width-' + postid).val('');
|
$( '#imgedit-sel-width-' + postid ).val( '' );
|
||||||
$('#imgedit-sel-height-' + postid).val('');
|
$( '#imgedit-sel-height-' + postid ).val( '' );
|
||||||
$('#imgedit-start-x-' + postid).val('0');
|
$( '#imgedit-start-x-' + postid ).val( '0' );
|
||||||
$('#imgedit-start-y-' + postid).val('0');
|
$( '#imgedit-start-y-' + postid ).val( '0' );
|
||||||
|
this.currentCropSelection = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1312,6 +1361,8 @@
|
||||||
img = $('#image-preview-' + postid), imgh = img.height(), imgw = img.width(),
|
img = $('#image-preview-' + postid), imgh = img.height(), imgw = img.width(),
|
||||||
sizer = this.hold.sizer, x1, y1, x2, y2, ias = this.iasapi;
|
sizer = this.hold.sizer, x1, y1, x2, y2, ias = this.iasapi;
|
||||||
|
|
||||||
|
this.currentCropSelection = null;
|
||||||
|
|
||||||
if ( false === this.validateNumeric( el ) ) {
|
if ( false === this.validateNumeric( el ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1335,18 +1386,19 @@
|
||||||
if ( x2 > imgw ) {
|
if ( x2 > imgw ) {
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
x2 = imgw;
|
x2 = imgw;
|
||||||
elX.val( Math.round( x2 / sizer ) );
|
elX.val( Math.min( this.hold.w, Math.round( x2 / sizer ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( y2 > imgh ) {
|
if ( y2 > imgh ) {
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
y2 = imgh;
|
y2 = imgh;
|
||||||
elY.val( Math.round( y2 / sizer ) );
|
elY.val( Math.min( this.hold.h, Math.round( y2 / sizer ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ias.setSelection( x1, y1, x2, y2 );
|
ias.setSelection( x1, y1, x2, y2 );
|
||||||
ias.update();
|
ias.update();
|
||||||
this.setCropSelection(postid, ias.getSelection());
|
this.setCropSelection(postid, ias.getSelection());
|
||||||
|
this.currentCropSelection = ias.getSelection();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -16,7 +16,7 @@
|
||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '6.7-alpha-58914';
|
$wp_version = '6.7-alpha-58915';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
|
Loading…
Reference in New Issue