ホームページ > バックエンド開発 > PHPチュートリアル > 液状化変形(前方変形)に関するご相談

液状化変形(前方変形)に関するご相談

WBOY
リリース: 2016-06-23 13:42:01
オリジナル
1282 人が閲覧しました

最後の質問の続き http://bbs.csdn.net/topics/390962881?page=1#post-398737904
液状化の式 U は解けましたが、実際に使用すると予想外の変形が見られますのでよくわかりません。リンクにエラーがあります。ガイドしてください

以下は私のコードです:

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 を使用するプロセスへ?
dstPixel と srcPixel はそれぞれ何ですか?値を割り当てる方法は?

アルゴリズムを見ると、srcPixels は getImageData メソッドで取得した画像データになるはずです
では、dstPixels はどのように割り当てられるのでしょうか。四角形の内接円部分を変更しただけなので
js配列は参照渡しです
コード内にdstPixels = srcPixelsがある場合、dstPixelsへの変更はsrcPixelsに影響します
なのでsrcPixels[sourcePosition + 0]が可能です先ほど変更した dstPixels[destPosition + 0]
これは間違っています
すべての変形データが生成されてからのみ書き戻すことができます


ご返信ありがとうございます、申し訳ありませんが、不足しているコードを埋めておきます

1. はい、キャンバスが使用されています
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
ログイン後にコピー


私の具体的な考えは、円内のピクセルを置き換えるだけです。すべての置換後のキャンバス、U の計算値は正しいと確信しています。何か誤解がありますか?私の置き換えの論理が正しいかどうかは現時点ではわかりません、私の資格が浅すぎて困っています。不足しているコードを入力します

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); //绘出圆形部分
ログイン後にコピー




私の具体的な考えは、現時点では、ピクセルを置き換えるだけであるということです。全ての置換が終わってからキャンバスに書き戻すのは本当ですし、計算された値は正しいです。何か間違っていますか?置換のロジックが正しいかどうかは、現時点ではわかりません。その式を理解できません。また、資格が浅すぎて問題がありません。あなたが遭遇した状況

function createCompatibleImageData(canvasId, imgData) {    "use strict";    var context2d = getContext2d(canvasId);    return context2d.createImageData(imgData.width, imgData.height);}
ログイン後にコピー

は、canvas context2d を定義するだけなので、pixwel を置き換えるという私の考えは間違っていますか?何をすべきでしょうか?

ありがとう!


処理は大まかにこんな感じ

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) //写回去}
ログイン後にコピー

処理時
srcPixels = source.data.concat([]); //これによりコピーが生成される(非参照)

dstPixels はsource.data



ではないどのような参照を指しているのかわかりますが、それはどういう意味ですか? (2つは同時に変更されます)
私のコード部分は参照(または引用)ではなく、一時的なコピーである必要があります

私が見ていた問題について考えましたが、アクションの範囲に問題がある可能性がありますか?

影響を受ける領域が原点 C から M (赤いブロック) に移動するとき



私の唯一の方法は、期待される画像の歪みを取得することですか?



完全なテスト例を書きましたので、参考にしてください (もちろん間違いもたくさんありますが、意味はあります)
画像上でマウスボタンを押してマウスをドラッグすると、効果が表示されます

すごいですね。 ..ありがとうマスターxuzuning、とても強力です! !

退屈して、ボード上の質問に答えてさまよっていました。とても楽しかったです〜

教えていただいたコードをテストして、注意深く調べてみたところ、実行原理は、あなたが書いた PHP バージョンのコードと同じのようです。前回与えてくれました (半径減少法を使用して) 実行しますか?)


これで目的は達成できますが、減量には現実的ではないかもしれません。

xuzuning、私がその公式を使用する方法について議論の余地があると思いますか?それとも諦めて別の道を探すべきでしょうか?

マウスを端から中心に移動すると、確かにいわゆる「ボディ」効果が生じます (パラメーターを変更してみてください)
ただし、この式は彼の説明どおりではないようです (逆になっているようです) )
もちろんそれも可能です プログラムが間違って書かれていた 集中的な記述方法を試しましたが、ほとんどが期待した結果を達成できませんでした。前回の PHP バージョンのみが最も明白な効果を持っています
もう一度見てみることができます






私はあなたが提供したコードで遊んでいますが、確かに減量を達成できますが、ユーザーが期待した結果を達成できない可能性があると思います(Meitu Xiuxiuのような結果を達成するには)。 。現時点では、同様の機能を実装している人はインターネット上に見つかりません。これは本当に難しいと思います。xuzuning さんの熱心なサポートに感謝します。もう少し時間をかけて調査してみます。xuzuning が新しいアイデアを見つけたら、ぜひ議論して私と共有してください。

また、PHP 掲示板では投稿を編集できないのは普通のことでしょうか? 他の人の質問に回答するときにタイプミスをしたのに、投稿者であるにも関わらず修正できませんでした。この記事では、自分の投稿を編集できませんでした。

投稿は公開後数分以内にのみ投稿者によって変更できます
それ以外の時間に投稿を変更する権限はモデレーターにあります。これが CSDN の規定です

アルゴリズムの問​​題については、モデレーターと議論されます。それを理解したら、プライベートメールを送ってください

投稿は公開後数分以内にのみ投稿者によって変更できます
それ以外の場合に変更する権限はモデレーターにあります。 . これは CSDN の規定です

アルゴリズムの問​​題については、理解した後で話し合います メールでお送りください



わかりました、ありがとうございます。
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート