世界快资讯丨基于.NetCore开发博客项目 StarBlog - (15) 生成随机尺寸图片
之前我写了一篇 .NetCore实现图片缩放与裁剪 - 基于ImageSharp,里面有生成尺寸随机图片的算法,同时也是StarBlog博客中原有的实现方式,不过偶尔刷新页面的时候我注意到有些图片加载不出来,调试了一下发现原来是报错了,原本这个算法有bug。于是利用周末时间重新实现了一遍,这下可以说是完美了~
生成随机尺寸图片的功能目前用在文章卡片上,原本使用的是LoremPicsum提供的服务,但它的服务器在国外,上线之后发现加载太慢了,经常加载不出来,于是决定自己实现一版。功能基础是上文提到的文章中的ImageSharp。
(资料图)
其他的还有诸如指定随机seed、将seed与图片进行静态映射等扩展功能的实现。
关键功能关键功能在于「根据指定的尺寸缩放或裁剪图片」
难点在于裁剪和缩放图片要保证:
不改变图片原有的比例尽量保持图片原有的内容元素第一版我是将横屏和竖屏的图片分开处理,(在输入尺寸不超过原图尺寸的情况下)先把比例接近的边调整成一样的大小,再裁剪中间部分,不过问题也很明显,如果调整大小之后另一条边的长度小于输入长度,那就会拉伸图片,导致比例改变。
在参考几个类似的MATLAB和Python项目之后,我换了别的思路:
在输入尺寸不超过原图尺寸的情况下,先按输入的尺寸比例裁剪、再调整尺寸如果超出原图尺寸,则先按比例调整原图的大小,再重复第一步举个例子比如原图是 1080 x 2340 的尺寸,输入的图片是 400 x 200 尺寸
那第一步判断尺寸不超过原图,不需要缩放
然后是「按输入的尺寸比例裁剪」,把 400 x 200 化简成 2 : 1 的比例
在原图中截取 2 : 1 的大小,即 1080 x 540
然后再把截取的图片调整到 400 x 200,搞定!
看下效果
原图 | 输出(400x200) | 输出(200x300) |
---|---|---|
虽然比一开始的方案更费一丢丢内存,但却实实在在提升了出图成功率,nice~
代码实现直接上代码好了,根据上面提到的思路,分两步走,代码也比一开始的方案更整洁
asyncTask<(Image,IImageFormat)>GenerateSizedImageAsync(stringimagePath,intwidth,intheight){awaitusingvarfileStream=newFileStream(imagePath,FileMode.Open);var(image,format)=awaitImage.LoadWithFormatAsync(fileStream);//输出尺寸超出原图片尺寸,放大if(width>image.Width&&height>image.Height){image.Mutate(a=>a.Resize(width,height));}elseif(width>image.Width||height>image.Height){//改变比例大的边if(width/image.Widtha.Resize(0,height));elseimage.Mutate(a=>a.Resize(width,0));}//将输入的尺寸作为裁剪比例var(scaleWidth,scaleHeight)=GetPhotoScale(width,height);varcropWidth=image.Width;varcropHeight=(int)(image.Width/scaleWidth*scaleHeight);if(cropHeight>image.Height){cropHeight=image.Height;cropWidth=(int)(image.Height/scaleHeight*scaleWidth);}varcropRect=newRectangle((image.Width-cropWidth)/2,(image.Height-cropHeight)/2,cropWidth,cropHeight);image.Mutate(a=>a.Crop(cropRect));image.Mutate(a=>a.Resize(width,height));return(image,format);}
里面还用到了计算图片比例,很简单,先算出图片宽度和高度的最大公约数,然后宽高分别除以这个最大公约数,就是比例了(也就是化简分数)
计算最大公约数代码
privatestaticintGetGreatestCommonDivisor(intm,intn){if(m计算图片比例代码
privatestatic(double,double)GetPhotoScale(intwidth,intheight){if(width==height)return(1,1);vargcd=GetGreatestCommonDivisor(width,height);return((double)width/gcd,(double)height/gcd);}参考资料Python PIL图片按比例裁剪:https://blog.csdn.net/lly1122334/article/details/122365539python 等比例裁剪图片:https://blog.csdn.net/chenping1993/article/details/110088858C#基础练习之求两个数的最大公约数与最小公倍数:https://blog.csdn.net/maybe_ice/article/details/104328202
相关阅读
-
世界热推荐:今晚7:00直播丨下一个突破...
今晚19:00,Cocos视频号直播马上点击【预约】啦↓↓↓在运营了三年... -
NFT周刊|Magic Eden宣布支持Polygon网...
Block-986在NFT这样的市场,每周都会有相当多项目起起伏伏。在过去... -
环球今亮点!头条观察 | DeFi的兴衰与...
在比特币得到机构关注之后,许多财务专家预测世界将因为加密货币的... -
重新审视合作,体育Crypto的可靠关系才能双赢
Block-987即使在体育Crypto领域,人们的目光仍然集中在FTX上。随着... -
简讯:前端单元测试,更进一步
前端测试@2022如果从2014年Jest的第一个版本发布开始计算,前端开发... -
焦点热讯:刘强东这波操作秀
近日,刘强东发布京东全员信,信中提到:自2023年1月1日起,逐步为...