时间:2021-07-01 10:21:17 帮助过:44人阅读
var r, alpha, angle, sourcePosition, destPosition, rmax, M, C, X;    for (y = -radius; y < radius; ++y) { //取得圆范围        for (x = -radius; x < radius; ++x) {            if (x * x + y * y <= radius * radius) {                destPosition = (y + centerY) * width + x + centerX; //移动後圆内1点(此为pixel位置,非座标)                destPosition *= 4;                var rmax = radius; //圆半径                C = {x:centerX+80,y:centerY};//移动前原点C (假设右往左移动80 pixel)                M = {x:centerX,y:centerY}; //移动後原点M                X = {x:(x + centerX) , y: (y+ centerY)};//移动後圆内1点座标                var U = Liquify(M,X,C,rmax); //液化运算得到 U 座标                sourcePosition = ((Math.ceil(U.y))*width)+Math.ceil(U.x); //粗略取整数 U 座标(尚未用线性插值法) 并转换为pixel位置                sourcePosition *= 4;                //用U取代原X像素                dstPixels[destPosition + 0] = srcPixels[sourcePosition + 0];                dstPixels[destPosition + 1] = srcPixels[sourcePosition + 1];                dstPixels[destPosition + 2] = srcPixels[sourcePosition + 2];                dstPixels[destPosition + 3] = srcPixels[sourcePosition + 3];            }         }    }    drawPixels(canvasId, destImgData); //绘图开始  
  用 Canvas 处理?  
 你的 dstPixels、srcPixels 分别是什么?怎么赋值的?  
  
 看算法 srcPixels 应该是 getImageData 方法取得的图片数据  
 那么 dstPixels 是如何赋值的?因为你只修改了矩形的内接圆部分  
 js 的数组是引用传递的  
 如果代码中有 dstPixels = srcPixels 的话,那么对 dstPixels 的修改就会作用到 srcPixels   
 于是 srcPixels[sourcePosition + 0] 得到的可能是前面刚被修改后的 dstPixels[destPosition + 0]  
 这样就不对了  
 只有在 变形数据全部生成后,才可写回去  
  
  
 
  谢谢回覆,抱歉,我把漏掉的代码补上  
  
 1. 对的,是用canvas  
 2. 遗漏代码:  
  
var sourceImgData = originalImageData; //原始图片image data var destImgData = createCompatibleImageData(canvasId,sourceImgData); //将image 写入Canvas var srcPixels = sourceImgData.data; //取得image data var dstPixels = destImgData.data; //取得Canvas内image data
  谢谢回覆,抱歉,我把漏掉的代码补上  
  
 1. 对的,是用canvas  
 2. 完整代码:  
  
     
  var sourceImgData = originalImageData; //原始图片image data    var destImgData = createCompatibleImageData(canvasId,sourceImgData); //将image 写入Canvas    var srcPixels = sourceImgData.data; //取得image data    var dstPixels = destImgData.data; //取得Canvas内image data    width = sourceImgData.width;    height = sourceImgData.height;    centerX = Math.floor(width / 2);     centerY = Math.floor(height / 2);    radius = 100;    copyImageData(srcPixels, dstPixels, width, height);    drawPixels(canvasId, destImgData); //绘出整张原图   var r, alpha, angle, sourcePosition, destPosition, rmax, M, C, X;    for (y = -radius; y < radius; ++y) { //取得圆范围        for (x = -radius; x < radius; ++x) {            if (x * x + y * y <= radius * radius) {                destPosition = (y + centerY) * width + x + centerX; //移动後圆内1点(此为pixel位置,非座标)                destPosition *= 4;                var rmax = radius; //圆半径                C = {x:centerX+80,y:centerY};//移动前原点C (假设右往左移动80 pixel)                M = {x:centerX,y:centerY}; //移动後原点M                X = {x:(x + centerX) , y: (y+ centerY)};//移动後圆内1点座标                var U = Liquify(M,X,C,rmax); //液化运算得到 U 座标                sourcePosition = ((Math.ceil(U.y))*width)+Math.ceil(U.x); //粗略取整数 U 座标(尚未用线性插值法) 并转换为pixel位置                sourcePosition *= 4;                 //用U取代原X像素                dstPixels[destPosition + 0] = srcPixels[sourcePosition + 0];                dstPixels[destPosition + 1] = srcPixels[sourcePosition + 1];                dstPixels[destPosition + 2] = srcPixels[sourcePosition + 2];                dstPixels[destPosition + 3] = srcPixels[sourcePosition + 3];            }         }    }    drawPixels(canvasId, destImgData); //绘出圆形部分    createCompatibleImageData 是个什么函数  
 如果 他返回的 destImgData 是传入的 sourceImgData 的引用的话,就会出现你遇到的情况 
function createCompatibleImageData(canvasId, imgData) {    "use strict";    var context2d = getContext2d(canvasId);    return context2d.createImageData(imgData.width, imgData.height);}    流程大致是这样  
  
var c=document.getElementById("myCanvas"); //获取 Canvas 控件var ctx=c.getContext("2d"); var img=new Image()img.src = '/photo.jpg';img.onload = function() { //加载图片  source = ctx.getImageData( x, y, w, h) //读取一个矩形区域  //在这里进行处理,注意事项在下面  ctx.putImageData(source, x, y) //写回去}    不太清楚您指的引用是什麽意思,是参照的意思吗?(2者会同步变化)  
 我的代码部分应该是复制一份暂存,不是参照(或引用)  
  
 我想了一下所看的问题,是否可能是作用区域有问题?  
 应该受影响的区域从原点C移动到M时(红色区块)  
    
  
 我的做法只有取得M圆内X点并算出U替换,作用区块也只有M圆,是否是这原因引起非预期图片变形?  
  
 
  我写了个完整的测试例,你可参考一下(当然毛病很多,但意思到了)  
 在图片上按下鼠标键并拖动鼠标就可看到效果  
鼠标位置:取景框:工作半径递减
  哇...谢谢xuzuning大神,太强大了!!  
  
 刚刚无聊也在板上乱晃回答问题 挺好玩的~  
  
 已经测试过您给的代码,也仔细看过,执行原理似乎跟您上次给的php版本代码一样(用递减半径的方式运行?)  
  
 这样子的确有达到目的,但是可能无法实际应用在瘦身功能。  
  
 xuzuning觉得我用那个公式的方式还有讨论的空间吗?还是我应该做罢寻求其他方式? 
  当你将鼠标从边缘向中心移动时,的确有所谓“?身“的效果(改变参数试试)  
 不过这个这个公式似乎并不像他描述的那样(好像反了)  
 当然也可能是程序写错了,我尝试了集中写法,大多都不能实现期望的结果。只有上次那个php版的效果最明显  
 你可以再看看 
  贴子只在发布后数分钟内贴主可修改  
 其他时间修改的权限在版主,CSDN就是这样规定的  
  
 算法问题待想明白后在于你商讨,你可以私信发个 email 给我 
   贴子只在发布后数分钟内贴主可修改   
 其他时间修改的权限在版主,CSDN就是这样规定的   
   
 算法问题待想明白后在于你商讨,你可以私信发个 email 给我