Liquefaction deformation (forward deformation) problem asking questions continue last time http://bbs.csdn.net/topics/390962881? Page = 1 # post-398737904
I have solved the liquefaction formula U, but the image is unexpectedly deformed after use. I'm not sure which part of the formula is wrong.
The following is my code:
Var r, alpha, angle, sourcePosition, destPosition, rmax, M, C, X; for (y =-radius; y <radius; ++ y) {// Obtain the circle range for (x =-radius; x <radius; ++ x) {if (x * x + y * y <= radius * radius) {destPosition = (y + centerY) * width + x + centerX; // move the first point in the back Circle (this is the pixel position, not the coordinate) destPosition * = 4; var rmax = radius; // circle radius C = {x: centerX + 80, y: centerY}; // Move the Origin C (assuming 80 pixel is moved from right to left) M = {x: centerX, y: centerY}; // Move the back point m x = {x :( x + centerX), y: (y + centerY )}; // Move the 1-point coordinate var U = Liquify (M, X, C, rmax) in the back circle; // Obtain the U coordinate sourcePosition = (Math. ceil (U. y) * width) + Math. ceil (U. x); // roughly take the integer U coordinate (linear interpolation is not used yet) and convert it to the pixel position sourcePosition * = 4; // replace the original X-pixel dstPixels [destPosition + 0] = srcPixels [sourcePosition + 0] with U; dstPixels [destPosition + 1] = srcPixels [sourcePosition + 1]; dstPixels [destPosition + 2] = srcPixels [sourcePosition + 2]; dstPixels [destPosition + 3] = srcPixels [sourcePosition + 3] ;}} drawPixels (canvasId, destImgData ); // start drawing
Image result after running:
Reply to discussion (solution)
Processing with Canvas?
What are your dstPixels and srcPixels? How to assign values?
View the image data obtained by the algorithm srcPixels using the getImageData method.
So how does dstPixels assign values? Because you only modified the inner circle of the rectangle
Js arrays are passed by reference.
If the code contains dstPixels = srcPixels, modifications to dstPixels will apply to srcPixels.
Therefore, srcPixels [sourcePosition + 0] may obtain the dstPixels [destPosition + 0] after the previous modification.
This is incorrect.
Data can be written back only after all the deformation data is generated.
Thank you for replying. sorry, I have added the missing code.
1. yes. canvas is used.
2. missing code:
Var sourceImgData = originalImageData; // original image data var destImgData = createCompatibleImageData (canvasId, sourceImgData); // write the image to the Canvas var srcPixels = sourceImgData. data; // Obtain image data var dstPixels = destImgData. data; // Obtain the image data in the Canvas
At present, I don't quite understand what you mean. my specific thinking is to replace pixel in the circle, but it is indeed written back to canvas after all the replications are completed, are you sure the value calculated by U is correct? I am not sure whether the logic for such replacement is correct or not. I cannot understand the formula, and my qualifications are too weak ..
Thank you for replying. sorry, I have added the missing code.
1. yes. canvas is used.
2. complete code:
Var sourceImgData = originalImageData; // original image data var destImgData = createCompatibleImageData (canvasId, sourceImgData); // write the image to the Canvas var srcPixels = sourceImgData. data; // Obtain image data var dstPixels = destImgData. data; // Obtain the image data width = sourceImgData in the Canvas. width; height = sourceImgData. height; centerX = Math. floor (width/2); centerY = Math. floor (height/2); radius = 100; copyImageData (srcPixels, dstPixels, width, height); drawPixels (canvasId, destImgData); // plot the entire source image var r, alpha, angle, sourcePosition, destPosition, rmax, M, C, X; for (y =-radius; y <radius; ++ y) {// Obtain the circle range for (x =-radius; x <radius; ++ x) {if (x * x + y * y <= radius * radius) {destPosition = (y + centerY) * width + x + centerX; // move the first point in the back Circle (this is the pixel position, not the coordinate) destPosition * = 4; var rmax = radius; // circle radius C = {x: centerX + 80, y: centerY}; // Move the Origin C (assuming 80 pixel is moved from right to left) M = {x: centerX, y: centerY}; // Move the back point m x = {x :( x + centerX), y: (y + centerY )}; // Move the 1-point coordinate var U = Liquify (M, X, C, rmax) in the back circle; // Obtain the U coordinate sourcePosition = (Math. ceil (U. y) * width) + Math. ceil (U. x); // roughly take the integer U coordinate (linear interpolation is not used yet) and convert it to the pixel position sourcePosition * = 4; // replace the original X-pixel dstPixels [destPosition + 0] = srcPixels [sourcePosition + 0] with U; dstPixels [destPosition + 1] = srcPixels [sourcePosition + 1]; dstPixels [destPosition + 2] = srcPixels [sourcePosition + 2]; dstPixels [destPosition + 3] = srcPixels [sourcePosition + 3] ;}} drawPixels (canvasId, destImgData ); // draw the circular area
At present, I don't quite understand what you mean. my specific thinking is to replace pixel in the circle, but it is indeed written back to canvas after all the replications are completed, are you sure the value calculated by U is correct? I am not sure whether the logic for such replacement is correct or not. I cannot understand the formula, and my qualifications are too weak ..
What is createCompatibleImageData?
If the returned destImgData is a reference to the imported sourceImgData, this will happen to you.
function createCompatibleImageData(canvasId, imgData) { "use strict"; var context2d = getContext2d(canvasId); return context2d.createImageData(imgData.width, imgData.height);}
It's just the definition of canvas context2d, so is my thinking about pixwel replacement wrong? What should I do?
Thank you!
The process is roughly like this
Var c = document. getElementById ("myCanvas"); // Obtain the var ctx = c. getContext ("2d"); var img = new Image () img. src = '/photo.jpg'; img. onload = function () {// Load image source = ctx. getImageData (x, y, w, h) // read a rectangular area // process it here. the precautions are described in ctx below. putImageData (source, x, y) // write back}
Processing time
SrcPixels = source. data. concat ([]); // This generates a copy (not referenced)
DstPixels is source. data
It is not clear what you mean by reference. does it mean by reference? (2 will change synchronously)
The part of my code should be copied for temporary storage instead of reference (or reference)
I thought about the question. Is it possible that there is a problem with the target region?
When the affected area is moved from Origin C to M (red block)
My practice is only to get X points in the M circle and calculate the U replacement, and the blocks only have M circles. is this caused unexpected image deformation?
I wrote a complete test example. you can refer to it (of course there are many problems, but I mean it)
Click the mouse button on the image and drag the mouse to see the effect.
Script start = 0; x = y = 0; r = 60; function $ (id) {return document. getElementById (id);} window. onload = function () {var c = $ ("myCanvas"); ctx = c. getContext ("2d"); var img = new Image () img. src = '/00.jpg'; // img of the image to be processed. onload = function () {c. width = this. width * 2 + 10; c. height = this. height; ctx. drawImage (img, 0, 0); ctx. drawImage (img, this. width + 10, 0); // I like to get a control group} window. onmouseup = function (e) {start = 0;} window. onmousedown = function (e) {$ ("mouse "). innerHTML = e. x + ',' + e. y; start = 1; x = e. x; y = e. y; r = parseInt ($ ('r '). value);} window. onmousemove = function (e) {if (start) {$ ("mouse "). innerHTML = e. x + ',' + e. y; forward (ctx, r, x, y, e. x, e. y) x = e. x; y = e. y; r-= $ ('DJ '). value ;}} function forward (im, r, cx, cy, mx, my) {var p = im. getImageData (cx-r, cy-r, r + r, r + r); $ ('box '). innerHTML = p. width + 'X' + p. height; var dst = p. data; var src = [], I; for (I = 0; I
Your browser does not support the canvas element.
Mouse position: Framing: working radiusDecrease
Wow... thank you, xuzuning! it's so powerful !!
It's fun to answer questions just when you're bored ~
I have tested the code you provided and read it carefully. the execution principle seems to be the same as that of the php version code you gave last time (run with a decreasing radius ?)
This does achieve the goal, but it may not be applied to the slimming function.
Does xuzuning still have room for discussion about the formula I used? Or should I ask for other methods?
When you move the mouse from the edge to the center, what is the so-called "? Body effect (try changing parameters)
However, this formula does not seem as he described (as if it was reversed)
Of course, it may be that the program is wrong. I tried to write it in a centralized manner, and most of them cannot achieve the expected results. Only the last php version has the most obvious effect.
You can check again
The code you provided can be reduced, but I think it cannot be used for commercial purposes, users may not be able to achieve the expected results (like Meitu Xiuxiu ). At present, I have not found half of the people who have implemented similar functions on the internet. I think this may be really difficult. thanks for the help of xuzuning! I will take some time to study it. if xuzuning finds a new idea, I would like to ask you to discuss it with me.
In addition, is it normal for PHP boards to be unable to edit posts? This is a problem. I cannot modify the incorrect words when answering questions from others. I always say that I have insufficient permissions. even if I am a poster, I cannot edit my post.
The post can only be modified within several minutes after it is published.
The permission to be modified at other times is specified by the moderator CSDN.
The question about the algorithm is discussed by you later. you can send an email to me via private message.
The post can only be modified within several minutes after it is published.
The permission to be modified at other times is specified by the moderator CSDN.
The question about the algorithm is discussed by you later. you can send an email to me via private message.
Thank you!