[英]How do I rotate and resize a canvas, while maintaining rotated aspect ratio, and resizing height?
I'm using phonegap, which is relatively unimportant to the question. 我正在使用phonegap,这个问题相对不重要。 When I take a vertical image, using capture.captureImage
, it comes back horizontal. 当我拍摄垂直图像时,使用capture.captureImage
,它将返回水平。
Anyways, I want to rotate the image vertically, like it was when I took the photo, expanding to the top and bottom of a newly created thumbnail that is 160px wide and 90px high (16:9) . 无论如何,我想像旋转照片一样垂直旋转图像,并扩展到新创建的缩略图的顶部和底部,该缩略图的宽度为160px,高度为90px (16:9) 。 I want to maintain its flipped aspect ratio (like it was when I took the pic) of 9:16 within the 16:9 taking up the entire height of the 90px high thumb. 我想在16:9内保持其9:16的翻转长宽比(就像我拍照片时一样) ,占用90px高拇指的整个高度。
Below I am showing the img
, although the code won't work unless you change the id='captured_img'
Element to a local URL, due to external image src
security problems with canvas.toDataURL()
. 在下面,我展示了img
,但是除非使用canvas.toDataURL()
导致外部图像src
安全问题,否则除非将id='captured_img'
元素更改为本地URL,否则代码将无法工作。 So <img width='160' height='90' id='captured_img' src='mustBeLocal.png' />
. 所以<img width='160' height='90' id='captured_img' src='mustBeLocal.png' />
。 If you want you can just right click and save the img
I provided. 如果需要,可以右键单击并保存我提供的img
。
If you run the tests, you will see that horizontal
works fine. 如果运行测试,您会发现horizontal
工作正常。 For reasons unknown to me, however, the vertical
test shows an image that appears smaller that its shown dimensions. 但是,出于我不知道的原因, vertical
测试显示的图像看起来比显示的尺寸小。
If you can point me in the right direction, I would appreciate it. 如果您能指出正确的方向,我将不胜感激。
var doc, M, I; onload = function(){ // make sure DOM is loaded doc = document; M = function(tag){ return doc.createElement(tag); } I = function(id){ return doc.getElementById(id); } var captured_img = I('captured_img'), canvas = M('canvas'), ctx = canvas.getContext('2d'), horizontal = I('horizontal'), vertical = I('vertical'); var output_img = I('output_img'); function reuse(force){ // just using force because you're not on your phone var iw = captured_img.width, ih = captured_img.height, w, h, hw = 0, hh = 0, s; if(force || innerWidth < innerHeight){ h = 50.625*iw/ih; w = h*ih/iw; s = true; } else{ w = 160; h = w*ih/iw; } canvas.width = w; canvas.height = h; console.log(w+'--'+h); // width and height are showing correctly // formula was also tested using a 400 x 300 image and aspect results look good to me - 4:3 90px high if(s){ hw = w/2; hh = h/2; ctx.translate(hw, hh); ctx.rotate(Math.PI/2); } ctx.drawImage(captured_img, -hw, -hh, w, h); output_img.src = canvas.toDataURL(); ctx.restore(); } horizontal.onclick = function(){ reuse(); } vertical.onclick = function(){ reuse(true); } }// end load
#container{ width:160px; height:90px; background:#000; text-align:center; } #output_img{ vertical-align:middle; } #captured_img,#container{ border:1px solid gold; } input[type=button]{ margin-top:5px; }
<!DOCTYPE html> <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'> <head> <meta charset='UTF-8' /><meta name='description' content='Test Page' /><meta name='keywords' content='test page, test template' /> <meta name='viewport' content='width=device-width, initial-scale=1.0' /> <title>Test Template</title> <link type='text/css' rel='stylesheet' href='external.css' /> <script type='text/javascript' src='external.js'></script> </head> <body> <div class='main'> <h2>160 x 90 - 16:9 aspect ratio</h2> <img width='160' height='90' id='captured_img' src='https://i.stack.imgur.com/nZQLy.png' alt='needs to be a local URL' /> <hr /> <div id='container'><img id='output_img' /></div> <input id='horizontal' type='button' value='horizontal' /> <input id='vertical' type='button' value='vertical' /> </div> </body> </html>
There's really no security error when you use a local URL. 使用本地URL时,实际上没有安全错误。 Just save my image and test on XAMPP or WAMP. 只需保存我的图像并在XAMPP或WAMP上进行测试。 Code and image are perfectly safe. 代码和图像非常安全。
After a bunch of random trial by error testing, I have concluded my reuse
function should look like: 经过一堆通过错误测试的随机试验后,我得出结论,我的reuse
函数应如下所示:
function reuse(force){ // just using force because you're not on your phone var iw = captured_img.width, ih = captured_img.height, w, h, hw, hh, s; if(force || innerWidth < innerHeight){ iw = ih; ih = captured_img.width; s = true; } if(iw/ih < 16/9){ h = 90; w = h*iw/ih; } else{ w = 160; h = w*ih/iw; } canvas.width = w; canvas.height = h; if(s){ hw = w/2; hh = h/2; ctx.save(); ctx.translate(hw, hh); ctx.rotate(Math.PI/2); ctx.drawImage(captured_img, -hh, -hw, h, w); ctx.restore(); } else{ ctx.drawImage(captured_img, 0, 0, w, h); } output_img.src = canvas.toDataURL(); }
It drove me crazy. 这让我发疯。 Hopefully this will help anyone with the same problem. 希望这将对遇到相同问题的任何人有所帮助。
PS PS
If you want anything to fit into any aspect ratio, all you would need to do is change the w
and h
var
s to match your width and height of your preferred aspect and make sure you change out that 16/9
with your w/h
. 如果您希望任何东西适合任何宽高比,则只需更改w
和h
var
使其与首选宽高比相匹配,并确保将w/h
更改为16/9
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.