问:
WebGL drawing 2D image with depth map to achieve pseudo-3D effect
I'm learning WebGL, done that with the help of WebGLFundamentals page, which helped me pretty much to understand how buffers, shaders and all that stuff works.
But now I want to achieve a certain effect which I saw here: https://tympanus.net/Tutorials/HeatDistortionEffect/index3.html
  I know how to make the heat distortion effect, the effect I want to achieve is the DEPTH on the image. This demo has a tutorial but it doesnt really explain how to do it, it says I must have a grayscale map, in which the white parts are the closest ones and the black parts the farest. But I really cant understand how it works, here is my shader's code:

```<code>var vertexShaderText = [
     "attribute vec2 a_position;",
     "attribute vec2 a_texCoord;",
     "uniform vec2 u_resolution;",
     "varying vec2 v_texCoord;",
     "void main() {",
     "  vec2 zeroToOne = a_position / u_resolution;",
     "  vec2 zeroToTwo = zeroToOne * 2.0;",
     "  vec2 clipSpace = zeroToTwo - 1.0;",
     "  gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);",
     "  v_texCoord = a_texCoord;",
     "}"
  ].join("\n")

  var fragShaderText = [
     "precision mediump float;",
     "uniform sampler2D u_image;",
     "uniform sampler2D u_depthMap;",
     "uniform vec2 mouse;",
     "varying vec2 v_texCoord;",
     "void main() {",
     "  float frequency=100.0;",
     "  float amplitude=0.010;",
     "  float distortion=sin(v_texCoord.y*frequency)*amplitude;",
     "  float map=texture2D(u_depthMap,v_texCoord).r;",
     "  vec4 color=texture2D(u_image,vec2(v_texCoord.x+distortion*map, v_texCoord.y));",
     "  gl_FragColor = color;",
     "}"
  ].join("\n")
</code>```

What I want is when I move the mouse, the image would respond to the shader to distort like in the link I showed above. But I really have no idea on how to do it on the javascript part.
Thanks

答:
Following the image processing tutorials from that same site shows how to load multiple images. The sample you linked to and the tutorial make it pretty clear how it works

First you need the original image

and you then apply a sine wave distortion.

"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg", crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }</code>```

<canvas id="canvas"></canvas>

```
</div>
</div>
</p>

<p>Then they also load a texture of multiple maps. This texture was created by hand in photoshop (or other image editing program). The green channel is how much to multiply the distortion by. The greener the more distortion.</p>

<p><img src="https://i.imgur.com/W9QazjL.jpg" alt=""></p>

<p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
<div class="snippet-code snippet-currently-hidden">
<pre class="snippet-code-js lang-js prettyprint-override"><code>"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg",
    crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  const mapTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/W9QazjL.jpg", crossOrigin: '',
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_mapImage: mapTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();</code>```

body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><canvas id="canvas"></canvas>

<script id="vs" type="f">
attribute vec2 position;
attribute vec2 texcoord;

uniform mat3 u_matrix;

varying vec2 v_texcoord;

void main() {
   gl_Position = vec4(u_matrix * vec3(position, 1), 1);
   v_texcoord = texcoord;
}
</script>
<script id="fs" type="f">
precision mediump float;

uniform float u_time;
uniform float u_distortionAmount;
uniform float u_distortionRange;

// our textures
uniform sampler2D u_originalImage;
uniform sampler2D u_mapImage;

// the texcoords passed in from the vertex shader.
varying vec2 v_texcoord;

void main() {
   vec4 depthDistortion = texture2D(u_mapImage, v_texcoord);
   float distortionMult = depthDistortion.g;  // just green channel

   vec2 distortion = vec2(
      sin(u_time + v_texcoord.y * u_distortionRange), 0) * u_distortionAmount;
   vec4 color0 = texture2D(u_originalImage, v_texcoord + distortion * distortionMult);
   gl_FragColor = color0;
}
</script>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script></code>```

Next there's an offset for the mouse multplied by another hand drawn map. This map is the red channel of the image above where the more red it is the more the mouse offset is applied. The map kind of represents depth. Since we need stuff in the front to move opposite of stuff in the back we need to convert that channel from 0 to 1 to -.5 to +.5 in the shader

"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg",
    crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  const mapTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/W9QazjL.jpg", crossOrigin: '',
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  const mouse = [0, 0];
  document.addEventListener('mousemove', (event) => {
    mouse[0] = (event.clientX / gl.canvas.clientWidth  * 2 - 1) * 0.05;
    mouse[1] = (event.clientY / gl.canvas.clientHeight * 2 - 1) * 0.05;
  });

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_mapImage: mapTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
      u_mouse: mouse,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }</code>```

<canvas id="canvas"></canvas>

```
</div>
</div>
</p>

<p>Finally, (not in the tutorial but in the sample) it loads a blurred version of the original image (blurred in some image editing program like photoshop)</p>

<p><img src="https://i.imgur.com/Zw7mMLX.jpg" alt=""></p>

<p>It might be hard to see it's blurred since the blurring is subtle.</p>

<p>The sample then uses the blurred image the more distorted things are</p>

<p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
<div class="snippet-code snippet-currently-hidden">
<pre class="snippet-code-js lang-js prettyprint-override"><code>"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg",
    crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  const mapTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/W9QazjL.jpg", crossOrigin: '',
  });

  const blurredTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/Zw7mMLX.jpg", crossOrigin: '',
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  const mouse = [0, 0];
  document.addEventListener('mousemove', (event) => {
    mouse[0] = (event.clientX / gl.canvas.clientWidth  * 2 - 1) * 0.05;
    mouse[1] = (event.clientY / gl.canvas.clientHeight * 2 - 1) * 0.05;
  });

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_mapImage: mapTexture,
      u_blurredImage: blurredTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
      u_mouse: mouse,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();</code>```

body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><canvas id="canvas"></canvas>

<!-- vertex shader -->
<script id="vs" type="f">
attribute vec2 position;
attribute vec2 texcoord;

uniform mat3 u_matrix;

varying vec2 v_texcoord;

void main() {
   gl_Position = vec4(u_matrix * vec3(position, 1), 1);
   v_texcoord = texcoord;
}
</script>
<!-- fragment shader -->
<script id="fs" type="f">
precision mediump float;

uniform float u_time;
uniform float u_distortionAmount;
uniform float u_distortionRange;
uniform vec2 u_mouse;

// our textures
uniform sampler2D u_originalImage;
uniform sampler2D u_blurredImage;
uniform sampler2D u_mapImage;

// the texcoords passed in from the vertex shader.
varying vec2 v_texcoord;

void main() {
   vec4 depthDistortion = texture2D(u_mapImage, v_texcoord);
   float distortionMult = depthDistortion.g;     // just green channel
   float parallaxMult = 0.5 - depthDistortion.r; // just red channel

   vec2 distortion = vec2(
      sin(u_time + v_texcoord.y * u_distortionRange), 0) * u_distortionAmount  * distortionMult;
   vec2 parallax = u_mouse * parallaxMult;

   vec2 uv = v_texcoord + distortion + parallax;
   vec4 original = texture2D(u_originalImage, uv);
   vec4 blurred = texture2D(u_blurredImage, uv);
   gl_FragColor = mix(original, blurred, length(distortion) / u_distortionAmount);
}
</script>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script></code>```

The finally big difference is rather than use a simple sine wave for distortion the shader on that sample is computing something slight more complicated.

cover

The code above uses a 2 unit quad that goes from -1 to +1 in X and Y. If you passed in an identiy matrix (or a 1,1 scale matrix which is the same thing) it would cover the canvas. Instead we want the image to not be distorted. To do that we had this code

```<code>const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const imageAspect = originalImage.width / originalImage.height;
const mat = m3.scaling(imageAspect / canvasAspect, -1);
</code>```

This just effectively says make it fill the canvas vertically and scale it in whatever it neesd to be to match the original image's aspect. The -1 is to flip the quad since otherwise the image is upside down.

To implement cover we just need to check if scale is < 1. If so it's not going to fill the canvas so we set the horizontal scale to 1 and adjust the vertical scale

```<code>// this assumes we want to fill vertically
let horizontalDrawAspect = imageAspect / canvasAspect;
let verticalDrawAspect = -1;
// does it fill horizontally?
if (horizontalDrawAspect < 1) {
  // no it does not so scale so we fill horizontally and
  // adjust vertical to match
  verticalDrawAspect /= horizontalDrawAspect;
  horizontalDrawAspect = 1;
}
const mat = m3.scaling(horizontalDrawAspect, verticalDrawAspect);
</code>```

Body:
I'm learning WebGL, done that with the help of WebGLFundamentals page, which helped me pretty much to understand how buffers, shaders and all that stuff works.
But now I want to achieve a certain effect which I saw here: https://tympanus.net/Tutorials/HeatDistortionEffect/index3.html
  I know how to make the heat distortion effect, the effect I want to achieve is the DEPTH on the image. This demo has a tutorial but it doesnt really explain how to do it, it says I must have a grayscale map, in which the white parts are the closest ones and the black parts the farest. But I really cant understand how it works, here is my shader's code:

var vertexShaderText = [
     "attribute vec2 a_position;",
     "attribute vec2 a_texCoord;",
     "uniform vec2 u_resolution;",
     "varying vec2 v_texCoord;",
     "void main() {",
     "  vec2 zeroToOne = a_position / u_resolution;",
     "  vec2 zeroToTwo = zeroToOne * 2.0;",
     "  vec2 clipSpace = zeroToTwo - 1.0;",
     "  gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);",
     "  v_texCoord = a_texCoord;",
     "}"
  ].join("\n")

  var fragShaderText = [
     "precision mediump float;",
     "uniform sampler2D u_image;",
     "uniform sampler2D u_depthMap;",
     "uniform vec2 mouse;",
     "varying vec2 v_texCoord;",
     "void main() {",
     "  float frequency=100.0;",
     "  float amplitude=0.010;",
     "  float distortion=sin(v_texCoord.y*frequency)*amplitude;",
     "  float map=texture2D(u_depthMap,v_texCoord).r;",
     "  vec4 color=texture2D(u_image,vec2(v_texCoord.x+distortion*map, v_texCoord.y));",
     "  gl_FragColor = color;",
     "}"
  ].join("\n")

What I want is when I move the mouse, the image would respond to the shader to distort like in the link I showed above. But I really have no idea on how to do it on the javascript part.
Thanks

Body:
Following the image processing tutorials from that same site shows how to load multiple images. The sample you linked to and the tutorial make it pretty clear how it works

First you need the original image

and you then apply a sine wave distortion.

"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg", crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();

body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }

<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<canvas id="canvas"></canvas>

<!-- vertex shader -->
<script id="vs" type="f">
attribute vec2 position;
attribute vec2 texcoord;

uniform mat3 u_matrix;

varying vec2 v_texcoord;

void main() {
   gl_Position = vec4((u_matrix * vec3(position, 1)).xy, 0, 1);
   v_texcoord = texcoord;
}
</script>
<!-- fragment shader -->
<script id="fs" type="x-shader/x-fragment">
precision mediump float;

uniform float u_time;
uniform float u_distortionAmount;
uniform float u_distortionRange;

// our textures
uniform sampler2D u_originalImage;

// the texcoords passed in from the vertex shader.
varying vec2 v_texcoord;

void main() {
   vec2 distortion = vec2(
      sin(u_time + v_texcoord.y * u_distortionRange), 0) * u_distortionAmount;
   vec4 original = texture2D(u_originalImage, v_texcoord + distortion);
   gl_FragColor = original;
}
</script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script>

Then they also load a texture of multiple maps. This texture was created by hand in photoshop (or other image editing program). The green channel is how much to multiply the distortion by. The greener the more distortion.

"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg",
    crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  const mapTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/W9QazjL.jpg", crossOrigin: '',
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_mapImage: mapTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();

body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }

<canvas id="canvas"></canvas>

<script id="vs" type="f">
attribute vec2 position;
attribute vec2 texcoord;

uniform mat3 u_matrix;

varying vec2 v_texcoord;

void main() {
   gl_Position = vec4(u_matrix * vec3(position, 1), 1);
   v_texcoord = texcoord;
}
</script>
<script id="fs" type="f">
precision mediump float;

uniform float u_time;
uniform float u_distortionAmount;
uniform float u_distortionRange;

// our textures
uniform sampler2D u_originalImage;
uniform sampler2D u_mapImage;

// the texcoords passed in from the vertex shader.
varying vec2 v_texcoord;

void main() {
   vec4 depthDistortion = texture2D(u_mapImage, v_texcoord);
   float distortionMult = depthDistortion.g;  // just green channel

   vec2 distortion = vec2(
      sin(u_time + v_texcoord.y * u_distortionRange), 0) * u_distortionAmount;
   vec4 color0 = texture2D(u_originalImage, v_texcoord + distortion * distortionMult);
   gl_FragColor = color0;
}
</script>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script>

Next there's an offset for the mouse multplied by another hand drawn map. This map is the red channel of the image above where the more red it is the more the mouse offset is applied. The map kind of represents depth. Since we need stuff in the front to move opposite of stuff in the back we need to convert that channel from 0 to 1 to -.5 to +.5 in the shader

"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg",
    crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  const mapTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/W9QazjL.jpg", crossOrigin: '',
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  const mouse = [0, 0];
  document.addEventListener('mousemove', (event) => {
    mouse[0] = (event.clientX / gl.canvas.clientWidth  * 2 - 1) * 0.05;
    mouse[1] = (event.clientY / gl.canvas.clientHeight * 2 - 1) * 0.05;
  });

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_mapImage: mapTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
      u_mouse: mouse,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();

body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }

<canvas id="canvas"></canvas>

<!-- vertex shader -->
<script id="vs" type="f">
attribute vec2 position;
attribute vec2 texcoord;

uniform mat3 u_matrix;

varying vec2 v_texcoord;

void main() {
   gl_Position = vec4(u_matrix * vec3(position, 1), 1);
   v_texcoord = texcoord;
}
</script>
<!-- fragment shader -->
<script id="fs" type="f">
precision mediump float;

uniform float u_time;
uniform float u_distortionAmount;
uniform float u_distortionRange;
uniform vec2 u_mouse;

// our textures
uniform sampler2D u_originalImage;
uniform sampler2D u_mapImage;

// the texcoords passed in from the vertex shader.
varying vec2 v_texcoord;

void main() {
   vec4 depthDistortion = texture2D(u_mapImage, v_texcoord);
   float distortionMult = depthDistortion.g;     // just green channel
   float parallaxMult = 0.5 - depthDistortion.r; // just red channel

   vec2 distortion = vec2(
      sin(u_time + v_texcoord.y * u_distortionRange), 0) * u_distortionAmount  * distortionMult;
   vec2 parallax = u_mouse * parallaxMult;

   vec4 color0 = texture2D(u_originalImage, v_texcoord + distortion + parallax);
   gl_FragColor = color0;
}
</script>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script>

Finally, (not in the tutorial but in the sample) it loads a blurred version of the original image (blurred in some image editing program like photoshop)

It might be hard to see it's blurred since the blurring is subtle.

The sample then uses the blurred image the more distorted things are

"use strict";

function main() {
  // Get A WebGL context
  /** @type {HTMLCanvasElement} */
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  if (!gl) {
    return;
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const originalTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/xKYRSwu.jpg",
    crossOrigin: '',
  }, (err, texture, source) => {
    originalImage = source;
  });

  const mapTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/W9QazjL.jpg", crossOrigin: '',
  });

  const blurredTexture = twgl.createTexture(gl, {
    src: "https://i.imgur.com/Zw7mMLX.jpg", crossOrigin: '',
  });

  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  const mouse = [0, 0];
  document.addEventListener('mousemove', (event) => {
    mouse[0] = (event.clientX / gl.canvas.clientWidth  * 2 - 1) * 0.05;
    mouse[1] = (event.clientY / gl.canvas.clientHeight * 2 - 1) * 0.05;
  });

  requestAnimationFrame(render);

  function render(time) {
    time *= 0.001;  // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    const mat = m3.scaling(imageAspect / canvasAspect, -1);

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, {
      u_matrix: mat,
      u_originalImage: originalTexture,
      u_mapImage: mapTexture,
      u_blurredImage: blurredTexture,
      u_distortionAmount: 0.003,  // .3%
      u_distortionRange: 100,
      u_time: time * 10,
      u_mouse: mouse,
    });

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    requestAnimationFrame(render);
  }
}

main();

body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }

<canvas id="canvas"></canvas>

<!-- vertex shader -->
<script id="vs" type="f">
attribute vec2 position;
attribute vec2 texcoord;

uniform mat3 u_matrix;

varying vec2 v_texcoord;

void main() {
   gl_Position = vec4(u_matrix * vec3(position, 1), 1);
   v_texcoord = texcoord;
}
</script>
<!-- fragment shader -->
<script id="fs" type="f">
precision mediump float;

uniform float u_time;
uniform float u_distortionAmount;
uniform float u_distortionRange;
uniform vec2 u_mouse;

// our textures
uniform sampler2D u_originalImage;
uniform sampler2D u_blurredImage;
uniform sampler2D u_mapImage;

// the texcoords passed in from the vertex shader.
varying vec2 v_texcoord;

void main() {
   vec4 depthDistortion = texture2D(u_mapImage, v_texcoord);
   float distortionMult = depthDistortion.g;     // just green channel
   float parallaxMult = 0.5 - depthDistortion.r; // just red channel

   vec2 distortion = vec2(
      sin(u_time + v_texcoord.y * u_distortionRange), 0) * u_distortionAmount  * distortionMult;
   vec2 parallax = u_mouse * parallaxMult;

   vec2 uv = v_texcoord + distortion + parallax;
   vec4 original = texture2D(u_originalImage, uv);
   vec4 blurred = texture2D(u_blurredImage, uv);
   gl_FragColor = mix(original, blurred, length(distortion) / u_distortionAmount);
}
</script>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script>

The finally big difference is rather than use a simple sine wave for distortion the shader on that sample is computing something slight more complicated.

cover

The code above uses a 2 unit quad that goes from -1 to +1 in X and Y. If you passed in an identiy matrix (or a 1,1 scale matrix which is the same thing) it would cover the canvas. Instead we want the image to not be distorted. To do that we had this code

const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const imageAspect = originalImage.width / originalImage.height;
const mat = m3.scaling(imageAspect / canvasAspect, -1);

This just effectively says make it fill the canvas vertically and scale it in whatever it neesd to be to match the original image's aspect. The -1 is to flip the quad since otherwise the image is upside down.

To implement cover we just need to check if scale is < 1. If so it's not going to fill the canvas so we set the horizontal scale to 1 and adjust the vertical scale

// this assumes we want to fill vertically
let horizontalDrawAspect = imageAspect / canvasAspect;
let verticalDrawAspect = -1;
// does it fill horizontally?
if (horizontalDrawAspect < 1) {
  // no it does not so scale so we fill horizontally and
  // adjust vertical to match
  verticalDrawAspect /= horizontalDrawAspect;
  horizontalDrawAspect = 1;
}
const mat = m3.scaling(horizontalDrawAspect, verticalDrawAspect);


来源: stackexchange

问:
Sample Grails web app: upload file, process it, download
I'm trying to make my first web app using Grails.

I want to upload a file, process it and return for download. I think it's a very common scheme and I believe there should be some sample app that does that.

I would like to use such and only change the processing part, implementing my own. It'd be the best if it was in Grails, but I guess anything else will work too. Well, the only problem might be that I have written my processing part in Groovy.

The help I'm seeking from you is whether you could provide me a source of such sample app/sample code/template so I could right away start implementing the processing part.

Obviously I've been searching for one to no avail.

I'm a newbie when it comes to web apps; I've only programmed some simple desktop apps, so if my question is inappropriate I'm terribly sorry.

Thanks in advance for all answers.

答:
I recommend taking a look to this guide: How to upload a file with Grails 3

For a quick answer, the steps you would need to take are:

In a view, create a form using the <g:uplodaForm> tag and add an <input type="file" name"myFile" /> element.

In the controller, get the file using def myFile = request.getFile("myFile").

In a controller, to recover a file from the disk (assuming png image):

```<code>File myFile = new File("/<file_path>/myFile")
render file: myFile.newInputStream(), contentType: 'image/png'
return
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I recommend taking a look to this guide: How to upload a file with Grails 3

For a quick answer, the steps you would need to take are:

In a view, create a form using the <g:uplodaForm> tag and add an <input type="file" name"myFile" /> element.

In the controller, get the file using def myFile = request.getFile("myFile").

In a controller, to recover a file from the disk (assuming png image):

File myFile = new File("/<file_path>/myFile")
render file: myFile.newInputStream(), contentType: 'image/png'
return


问:
Passing data between components using reactjs
I have a div like following.

```<code><div className="horiz_center" onClick={this.textType.bind(this,'text')}>
   <img src={StarIcon} className="post_type_icon"/>
   <a className="post_type_text">Text</a>
</div>
</code>```

I can get the value with this function

```<code>textType(postType) {

        this.setState({postType});

}
</code>```

My question is if i want to use postType in another component, how can i pass it to that component?

答:
```<code>const {postType} = this.state;
<MyComponent postType={postType} />
</code>```

And in your component ( MyComponent ) access your properties like

```<code>this.props.postType
</code>```

Body:
I have a div like following.

   Text

I can get the value with this function

textType(postType) {

        this.setState({postType});

}

My question is if i want to use postType in another component, how can i pass it to that component?

Body:
const {postType} = this.state;
<MyComponent postType={postType} />

And in your component ( MyComponent ) access your properties like

this.props.postType


问:
Renaming an image during the uploading PHP Mysql
Using the following code could someone explain to me how I can rename the image files to a misc name during the upload process?

Here is what I'm working with.

uploader.php

```<code><?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
$dataType = mysql_real_escape_string($_POST["dataType"]);
$title = mysql_real_escape_string($_POST["title"]);
$fileName = basename($_FILES["image"]["name"]);
$target_path = ($_SERVER['DOCUMENT_ROOT'] . "/images/gallery/".$fileName);
if (file_exists($target_path))
{
    echo "An image with that file name already exists.";
}
elseif (move_uploaded_file($_FILES["image"]["tmp_name"], $target_path))
{
    // The file is in the images/gallery folder. Insert record into database by
    // executing the following query:
     $sql="INSERT INTO images (data_type, title, file_name)"."VALUES('$dataType','$title','$fileName')";
     $retval = mysql_query($sql);

    echo "The image was successfully uploaded and added to the gallery :) <a href='index.php'>Add another image</a>";

}
else
{
    echo "There was an error uploading the file, please try again!";
}
?>
</code>```

Then here is my code for uploading the image to the gallery.

```<code><form enctype="multipart/form-data" action="uploader.php" method="POST">

        Category: <select class="text" name="dataType">
        <option value="treeremoval" selected="selected">treeremoval</option>
        <option value="treetrimming" >treetrimming</option>
        <option value="treebracing" >treebracing</option>
        <option value="stumpgrinding" >stumpgrinding</option>
        <option value="firewood" >firewood</option>
        <option value="cleanup" >cleanup</option>
        </select><br />
<br />

    Caption: <input type="text" name="title"><br />
<br />

    Image to upload: <input type="file" name="image"><br />
<br />

    <input type="submit" value="Upload">
</form>
</code>```

I am very new to using php and mysql so any help would be appreciated. I have some other questions too, but I guess I should ask one at a time. =)

Thank You!

答:
i would suggest upload a secure image format and restrict file size</p>

```<code>           //image upload
            $pro_image = $_FILES['image']['name'];
            $pro_image_tmp = $_FILES['image']['tmp_name'];

            $fileType = $_FILES["image"]["type"];
            $fileSize = $_FILES["image"]["size"];
            $fileErrorMsg = $_FILES["image"]["error"];

             $fileName = preg_replace('#[^a-z.0-9]#i', '', $pro_image);
             $nwtourimg = explode(".", $fileName);
             if (!$pro_image_tmp) { // if file not chosen
                echo "ERROR: Please browse for a file before clicking the upload button.";
                exit();
            } else if($fileSize > 5242880) { // if file size is larger than 5 Megabytes
                echo "ERROR: Your file was larger than 5 Megabytes in size.";
                unlink($pro_image_tmp); // Remove the uploaded file from the PHP temp folder
                exit();
            } else if (!preg_match("/.(gif|jpg|png|jpeg)$/i", $fileName) ) {
                 // This condition is only if you wish to allow uploading of specific file types
                 echo "ERROR: Your image was not .gif, .jpg, or .png.";
                 unlink($pro_image_tmp); // Remove the uploaded file from the PHP temp folder
                 exit();
            } else if ($fileErrorMsg == 1) { // if file upload error key is equal to 1
                echo "ERROR: An error occured while processing the file. Try again.";
                exit();
            }

             $fileExt = end($nwtourimg);
             $fileName = time().rand().".".$fileExt;

             move_uploaded_file("$pro_image_tmp","upload/$fileName");
                //image upload end
</code>```

Body:
Using the following code could someone explain to me how I can rename the image files to a misc name during the upload process?

Here is what I'm working with.

uploader.php

<?php
include($_SERVER['DOCUMENT_ROOT'] . "/connections/dbconnect.php");
$dataType = mysql_real_escape_string($_POST["dataType"]);
$title = mysql_real_escape_string($_POST["title"]);
$fileName = basename($_FILES["image"]["name"]);
$target_path = ($_SERVER['DOCUMENT_ROOT'] . "/images/gallery/".$fileName);
if (file_exists($target_path))
{
    echo "An image with that file name already exists.";
}
elseif (move_uploaded_file($_FILES["image"]["tmp_name"], $target_path))
{
    // The file is in the images/gallery folder. Insert record into database by
    // executing the following query:
     $sql="INSERT INTO images (data_type, title, file_name)"."VALUES('$dataType','$title','$fileName')";
     $retval = mysql_query($sql);

    echo "The image was successfully uploaded and added to the gallery :) Add another image";

}
else
{
    echo "There was an error uploading the file, please try again!";
}
?>

Then here is my code for uploading the image to the gallery.

<form enctype="multipart/form-data" action="uploader.php" method="POST">

        Category: <select class="text" name="dataType">
        <option value="treeremoval" selected="selected">treeremoval</option>
        <option value="treetrimming" >treetrimming</option>
        <option value="treebracing" >treebracing</option>
        <option value="stumpgrinding" >stumpgrinding</option>
        <option value="firewood" >firewood</option>
        <option value="cleanup" >cleanup</option>
        </select>

    Caption: <input type="text" name="title">

    Image to upload: <input type="file" name="image">

    <input type="submit" value="Upload">
</form>

I am very new to using php and mysql so any help would be appreciated. I have some other questions too, but I guess I should ask one at a time. =)

Thank You!

Body:
i would suggest upload a secure image format and restrict file size

           //image upload
            $pro_image = $_FILES['image']['name'];
            $pro_image_tmp = $_FILES['image']['tmp_name'];

            $fileType = $_FILES["image"]["type"];
            $fileSize = $_FILES["image"]["size"];
            $fileErrorMsg = $_FILES["image"]["error"];

             $fileName = preg_replace('#[^a-z.0-9]#i', '', $pro_image);
             $nwtourimg = explode(".", $fileName);
             if (!$pro_image_tmp) { // if file not chosen
                echo "ERROR: Please browse for a file before clicking the upload button.";
                exit();
            } else if($fileSize > 5242880) { // if file size is larger than 5 Megabytes
                echo "ERROR: Your file was larger than 5 Megabytes in size.";
                unlink($pro_image_tmp); // Remove the uploaded file from the PHP temp folder
                exit();
            } else if (!preg_match("/.(gif|jpg|png|jpeg)$/i", $fileName) ) {
                 // This condition is only if you wish to allow uploading of specific file types
                 echo "ERROR: Your image was not .gif, .jpg, or .png.";
                 unlink($pro_image_tmp); // Remove the uploaded file from the PHP temp folder
                 exit();
            } else if ($fileErrorMsg == 1) { // if file upload error key is equal to 1
                echo "ERROR: An error occured while processing the file. Try again.";
                exit();
            }

             $fileExt = end($nwtourimg);
             $fileName = time().rand().".".$fileExt;

             move_uploaded_file("$pro_image_tmp","upload/$fileName");
                //image upload end


问:
Adding Action to button in HTML
```<code><html>
<%@ page import="java.sql.*" %>
<head>
<title>Sarvotam List</title>
<link rel="stylesheet" href="Styles/main.css">
</head>
<body>
<div class="seg">
    <form action="main.jsp" method="post">
    <table class="data" align="center" width=80%>
        <tr>
            <th width=20%>Qualification Exam</th>
            <th width=20%>Course Type</th>
            <th width=20%>Duration</th>
            <th width=20%>Number of Cheques</th>
            <th width=20%>Course_Category</th>
        </tr>
        <tr>
            <td width=20% align="center"><input type="text" name="qual"
  width=20%></td>
            <td width=20% align="center"><input type="text" name="ctype"
  width=20%></td>
            <td width=20% align="center"><input type="number" name="dur"
  width=20%></td>
            <td width=20% align="center"><input type="number" name="che"
width=20%></td>
            <td width=20% align="center"><select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>
        </tr>
        <tr>
            <td width=20% align="center"><input type="text" name="qual"
 width=20%></td>
            <td width=20% align="center"><input type="text" name="ctype"
width=20%></td>
            <td width=20% align="center"><input type="number" name="dur"
     width=20%></td>
            <td width=20% align="center"><input type="number" name="che"
width=20%></td>
            <td width=20% align="center"><select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>
        </tr>
        <tr>
            <td width=20% align="center"><input type="text" name="qual"
width=20%></td>
            <td width=20% align="center"><input type="text" name="ctype"
width=20%></td>
            <td width=20% align="center"><input type="number" name="dur"
width=20%></td>
            <td width=20% align="center"><input type="number" name="che"
width=20%></td>
            <td width=20% align="center"><select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>
        </tr>
        <tr>
            <td width=20% align="center"><input type="text" name="qual"
width=20%></td>
            <td width=20% align="center"><input type="text" name="ctype"
width=20%></td>
            <td width=20% align="center"><input type="number" name="dur"
width=20%></td>
            <td width=20% align="center"><input type="number" name="che"
width=20%></td>
            <td width=20% align="center"><select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>
        </tr>
        <tr>
            <td width=20% align="center"><input type="text" name="qual"
  width=20%></td>
            <td width=20% align="center"><input type="text" name="ctype"
 width=20%></td>
            <td width=20% align="center"><input type="number" name="dur"
    width=20%></td>
            <td width=20% align="center"><input type="number" name="che"
width=20%></td>
            <td width=20% align="center"><select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>
        </tr>
            </table>
        <center><button id="submit" name="save">Submit</button></center>

<%              try{
    ResultSet rs=null;
    Statement st=null;
    Connection conn = null;
    Class.forName("oracle.jdbc.driver.OracleDriver");
            conn =
   DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
   "system", "parents94");
            st=conn.createStatement();
            int i=0;
            String s = request.getParameter("save");
            String[] qual=request.getParameterValues("qual");
            String[] ctype=request.getParameterValues("ctype");
            String[] dur=request.getParameterValues("dur");
            String[] noc=request.getParameterValues("che");
            String[] cou=request.getParamterValues("opt");
            if(s!=null)
            while(qual[i].length()!=0){
                st.executeUpdate("insert into SCHOL_COURSE_MASTER values('"+qual[i]+"','"+ctype[i]+"','"+dur[i]+"','"+noc[i]+"','"+cou[i]+"')");
                i++;
            }
        conn.close();
        st.close();
            }
catch(Exception e)
    {
        e.getMessage();
    }
%>
</form>
</div>
  </body>
 </html>
</code>```

This is my code
I need to take inputs from user in the table and add to the database
All the connections work
But the sql query does not lead to any changes in the data base
I just need help in how to code it to work on press of submit button

答:
first you might want to check if
the click event was triggered?

then try to print if the you get the correct values or if it is not null

if you there are error its better if you include it in your post

Title: Adding Action to button in HTML

Body:
<%@ page import="java.sql.*" %>

<title>Sarvotam List</title>
<link rel="stylesheet" href="Styles/main.css">

    <form action="main.jsp" method="post">

            Qualification Exam
            Course Type
            Duration
            Number of Cheques
            Course_Category

            <input type="text" name="qual"
  width=20%>
            <input type="text" name="ctype"
  width=20%>
            <input type="number" name="dur"
  width=20%>
            <input type="number" name="che"
width=20%>
            <select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>

            <input type="text" name="qual"
 width=20%>
            <input type="text" name="ctype"
width=20%>
            <input type="number" name="dur"
     width=20%>
            <input type="number" name="che"
width=20%>
            <select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>

            <input type="text" name="qual"
width=20%>
            <input type="text" name="ctype"
width=20%>
            <input type="number" name="dur"
width=20%>
            <input type="number" name="che"
width=20%>
            <select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>

            <input type="text" name="qual"
width=20%>
            <input type="text" name="ctype"
width=20%>
            <input type="number" name="dur"
width=20%>
            <input type="number" name="che"
width=20%>
            <select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>

            <input type="text" name="qual"
  width=20%>
            <input type="text" name="ctype"
 width=20%>
            <input type="number" name="dur"
    width=20%>
            <input type="number" name="che"
width=20%>
            <select name="opt">
                    <option id="ENG">ENG</option>
                    <option id="MED">MED</option>
                    <option id="OTH">OTH</option>
                    <option id="PG">PG</option>
                </select>

        <button id="submit" name="save">Submit</button>

<%              try{
    ResultSet rs=null;
    Statement st=null;
    Connection conn = null;
    Class.forName("oracle.jdbc.driver.OracleDriver");
            conn =
   DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
   "system", "parents94");
            st=conn.createStatement();
            int i=0;
            String s = request.getParameter("save");
            String[] qual=request.getParameterValues("qual");
            String[] ctype=request.getParameterValues("ctype");
            String[] dur=request.getParameterValues("dur");
            String[] noc=request.getParameterValues("che");
            String[] cou=request.getParamterValues("opt");
            if(s!=null)
            while(qual[i].length()!=0){
                st.executeUpdate("insert into SCHOL_COURSE_MASTER values('"+qual[i]+"','"+ctype[i]+"','"+dur[i]+"','"+noc[i]+"','"+cou[i]+"')");
                i++;
            }
        conn.close();
        st.close();
            }
catch(Exception e)
    {
        e.getMessage();
    }
%>
</form>

This is my code
I need to take inputs from user in the table and add to the database
All the connections work
But the sql query does not lead to any changes in the data base
I just need help in how to code it to work on press of submit button


问:
@XmlElementWrapper not taken into account in XML/REST Spring webservice
I want to give custom names to the xml root element and to list elements.
But the annotations don't work.

```<code>@XmlRootElement(name = "test")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestRsp {
    @XmlElementWrapper(name = "persons")
    @XmlElement(name = "pax")
    private List<Person> persons;
}

public class Person {
   private String name;
   private String age;
}
</code>```

Usage:

```<code>@RestController
public class MyServlet {
   @RequestMapping("/test")
   public TestRsp test() {
      //...
      return rsp;
   }
}
</code>```

Result:

```<code><TestRsp> <!-- should be named "test" -->
   <persons>
     <persons> <!-- should be named "pax" -->
       <name />
       <age />
     </persons>
     <persons>
        //...
     </persons>
   </persons>
</TestRsp>
</code>```

So my xml annotations are not picked up. But why?

答:
Try using @JsonProperty annotation.

It should look something like thit:

```<code>@JsonProperty("test")
</code>```

EDIT 1:

Try annotating the getter of the fields that you want to change like so:

```<code>@XmlElement(name="someName")
</code>```

EDIT 2:

```<code>@XmlRootElement(name="persons")
public class Root {

    private List<String> someList;

    @XmlElement(name="pax")
    public List<String> getSomeList() {
        return someList;
    }

    public void setSomeList(List<String> someList) {
        this.someList = someList;
    }

    public Root(String numValue,List<String> someListValue) {
        this();
        this.number = numValue;
        this.someList = someListValue;
    }

    /**
     *
     */
    public Root() {
        // TODO Auto-generated constructor stub
    }
}
</code>```

Maybe this will provide:

```<code> <persons>
    <pax>FOO</pax>
    <pax>BAR</pax>
 </persons>
</code>```

EDIT 3:

Maybe if you want to make your solution works you need to add a file called jaxb.properties in with your model classes with the following entry:

```<code>javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
</code>```

Body:
I want to give custom names to the xml root element and to list elements.
But the annotations don't work.

@XmlRootElement(name = "test")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestRsp {
    @XmlElementWrapper(name = "persons")
    @XmlElement(name = "pax")
    private List<Person> persons;
}

public class Person {
   private String name;
   private String age;
}

Usage:

@RestController
public class MyServlet {
   @RequestMapping("/test")
   public TestRsp test() {
      //...
      return rsp;
   }
}

Result:

<TestRsp>
   <persons>
     <persons>
       <name />
       <age />
     </persons>
     <persons>
        //...
     </persons>
   </persons>
</TestRsp>

So my xml annotations are not picked up. But why?

Body:
Try using @JsonProperty annotation.

It should look something like thit:

@JsonProperty("test")

EDIT 1:

Try annotating the getter of the fields that you want to change like so:

@XmlElement(name="someName")

EDIT 2:

@XmlRootElement(name="persons")
public class Root {

    private List<String> someList;

    @XmlElement(name="pax")
    public List<String> getSomeList() {
        return someList;
    }

    public void setSomeList(List<String> someList) {
        this.someList = someList;
    }

    public Root(String numValue,List<String> someListValue) {
        this();
        this.number = numValue;
        this.someList = someListValue;
    }

    /**
     *
     */
    public Root() {
        // TODO Auto-generated constructor stub
    }
}

Maybe this will provide:

 <persons>
    <pax>FOO</pax>
    <pax>BAR</pax>
 </persons>

EDIT 3:

Maybe if you want to make your solution works you need to add a file called jaxb.properties in with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory


问:
Setters: Consumer vs. direct method call
Why would you use a Consumer

```<code>public Consumer<String> setValue();
</code>```

instead of direct function call

```<code>public void setValue(String value);
</code>```

for setters?

I only see disadvantages:

the direct method call is more readable

another disadvantage of the Consumer variant is, that the calling code must always handle exceptions explicitly

```<code>try {
    instance.setValue().accept("newValue");
} catch (Exception e) {
    // handle exception
}
</code>```

答:
You must use the Consumer, when you cannot use method references for some reason: e.g. when you target older Android versions, that don't support Java8.

Note: with the new Android toolchain, Java8 method references are supported directly (even without Retrolambda, etc.), so this is not required anymore.

Thanks to Jake Wharton who answered in rx-preferences #96

Body:
Why would you use a Consumer

public Consumer<String> setValue();

instead of direct function call

public void setValue(String value);

for setters?

I only see disadvantages:

the direct method call is more readable

another disadvantage of the Consumer variant is, that the calling code must always handle exceptions explicitly

try {
    instance.setValue().accept("newValue");
} catch (Exception e) {
    // handle exception
}


问:
C# Console Application display invalid input in while loop
I have this C# console application code here that reads text from a file.
when a user inputs a value, it searches the file for lines that contain that value.
In my case, the console will ask for a room number, the console will then search room.txt for the room number thats split with ','

```<code>class Program
{
    static void Main(string[] args)
    {
        int counter = 0;
        string line;
        string roomNumber;

        Console.WriteLine("Enter room number");
        roomNumber = Console.ReadLine();
        // Read the file and display it line by line.
        System.IO.StreamReader file = new
              System.IO.StreamReader("room.txt");
        while ((line = file.ReadLine()) != null)
        {
            string[] words = line.Split(',');
            if (roomNumber == words[1])
            {
                Console.WriteLine(line);
            }
                counter++;
        }

        file.Close();

        // Suspend the screen.
         Console.ReadLine();
        }
    }
}
</code>```

How do i make it so that it will write "Invalid room number" when it cant find it in the text file, and then loop back to asking the room number.

答:
I would read the entire file at once, construct an enumerable from it and try to find the first match:

```<code>bool found = false;

do
{
    Console.WriteLine("Enter room number");
    string roomNumber = Console.ReadLine();

    using (StreamReader file = new StreamReader("room.txt"))
    {
        string str = file.ReadToEnd();
        string[] rooms = str.Split(new char[] { '\r', '\n', ',' }, StringSplitOptions.RemoveEmptyEntries);

        if (!rooms.Any(room => room == roomNumber))
        {
            Console.WriteLine("Invalid room");
        }
        else
        {
            Console.WriteLine($"Found room {roomNumber}");
            found = true;
        }
    }
}
while (!found);
</code>```

This code uses LINQ to find the first match (Any) on your input array. Then it will display a message if it has found the room or not. Also note the using, which makes your file stream close nicely, even when an exception occurs.

Body:
I have this C# console application code here that reads text from a file.
when a user inputs a value, it searches the file for lines that contain that value.
In my case, the console will ask for a room number, the console will then search room.txt for the room number thats split with ','

class Program
{
    static void Main(string[] args)
    {
        int counter = 0;
        string line;
        string roomNumber;

        Console.WriteLine("Enter room number");
        roomNumber = Console.ReadLine();
        // Read the file and display it line by line.
        System.IO.StreamReader file = new
              System.IO.StreamReader("room.txt");
        while ((line = file.ReadLine()) != null)
        {
            string[] words = line.Split(',');
            if (roomNumber == words[1])
            {
                Console.WriteLine(line);
            }
                counter++;
        }

        file.Close();

        // Suspend the screen.
         Console.ReadLine();
        }
    }
}

How do i make it so that it will write "Invalid room number" when it cant find it in the text file, and then loop back to asking the room number.

Body:
I would read the entire file at once, construct an enumerable from it and try to find the first match:

bool found = false;

do
{
    Console.WriteLine("Enter room number");
    string roomNumber = Console.ReadLine();

    using (StreamReader file = new StreamReader("room.txt"))
    {
        string str = file.ReadToEnd();
        string[] rooms = str.Split(new char[] { '\r', '\n', ',' }, StringSplitOptions.RemoveEmptyEntries);

        if (!rooms.Any(room => room == roomNumber))
        {
            Console.WriteLine("Invalid room");
        }
        else
        {
            Console.WriteLine($"Found room {roomNumber}");
            found = true;
        }
    }
}
while (!found);

This code uses LINQ to find the first match (Any) on your input array. Then it will display a message if it has found the room or not. Also note the using, which makes your file stream close nicely, even when an exception occurs.


问:
eclipse plugin setBounds attribute not working
I am developing an eclipse plugin wherein I wanted to show a label and a progress bar.But unfortunately I am unable to change their size.Whatever size I mention in setBounds attribute of label and progressBar,gives me the coordinates:Rectangle {3, 3, 70, 15} and Rectangle {3, 21, 170, 17}

Below is my handler code:

```<code>private ProgressBar progressBar;
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {

        Display display = Display.getDefault();

        Shell p_shell = new Shell(display,SWT.DIALOG_TRIM);

        p_shell.setText("Translating..");

        p_shell.setLayout(new RowLayout(SWT.VERTICAL));

        p_shell.setSize(250, 70);

        Label label = new Label(p_shell, SWT.NONE);

        label.setBounds(10, 20, 180, 20);
        //LINE 101 gives Rectangle {3, 3, 70, 15}

        label.setText("Please wait ...");

        progressBar = new ProgressBar(p_shell, SWT.SMOOTH);

        //progressBar.setBounds(10, 50, 200, 20);
        //LINE 100 gives Rectangle {3, 21, 170, 17}

        progressBar.setBounds(new Rectangle(5, 30, 150, 10));
        //LINE 100 gives Rectangle {3, 21, 170, 17}

        progressBar.setMinimum(30);

        progressBar.setMaximum(100);

        p_shell.open();

        System.out.println("progress bar  ==> " + progressBar.getBounds());//LINE 100

        System.out.println("label ==> " + label.getBounds());//LINE 101

        while(!p_shell.isDisposed()){

            if(!display.readAndDispatch()){
                display.sleep();
            }
        }
        }
</code>```

I am unable to proceed further.Any help would be greatly appreciated.

答:
You can't mix a Layout with setBounds - the layout will override the bounds. If you remove the setLayout the bounds will work.

However using setBounds is likely to give you problems on different screens so you should try and make this work using layouts with no setBounds.

Also note that Eclipse wizards, Jobs and other things already provide standard progress indicators.

Body:
I am developing an eclipse plugin wherein I wanted to show a label and a progress bar.But unfortunately I am unable to change their size.Whatever size I mention in setBounds attribute of label and progressBar,gives me the coordinates:Rectangle {3, 3, 70, 15} and Rectangle {3, 21, 170, 17}

Below is my handler code:

private ProgressBar progressBar;
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {

        Display display = Display.getDefault();

        Shell p_shell = new Shell(display,SWT.DIALOG_TRIM);

        p_shell.setText("Translating..");

        p_shell.setLayout(new RowLayout(SWT.VERTICAL));

        p_shell.setSize(250, 70);

        Label label = new Label(p_shell, SWT.NONE);

        label.setBounds(10, 20, 180, 20);
        //LINE 101 gives Rectangle {3, 3, 70, 15}

        label.setText("Please wait ...");

        progressBar = new ProgressBar(p_shell, SWT.SMOOTH);

        //progressBar.setBounds(10, 50, 200, 20);
        //LINE 100 gives Rectangle {3, 21, 170, 17}

        progressBar.setBounds(new Rectangle(5, 30, 150, 10));
        //LINE 100 gives Rectangle {3, 21, 170, 17}

        progressBar.setMinimum(30);

        progressBar.setMaximum(100);

        p_shell.open();

        System.out.println("progress bar  ==> " + progressBar.getBounds());//LINE 100

        System.out.println("label ==> " + label.getBounds());//LINE 101

        while(!p_shell.isDisposed()){

            if(!display.readAndDispatch()){
                display.sleep();
            }
        }
        }

I am unable to proceed further.Any help would be greatly appreciated.


问:
Addressing instance name string in __init__(self) in Python
I am doing something like this:

```<code>class Class(object):
    def __init__(self):
        self.var=#new instance name string#
</code>```

How do I make the __ init __ method of my instance to use the instance name string for 'c'? Say in case:

```<code>c=Class()
</code>```

I want c.var equal to 'c'.

Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

```<code>c=Class()
</code>```

Then, suppose:

```<code>del c
</code>```

Later on:

```<code>c=Class()
</code>```

sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

```<code>c=Class()
</code>```

Then, suppose:

```<code>del c
</code>```

Later on:

```<code>c=Class()
</code>```

sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

答:
This is a scope issue, you can't do what you're asking.  Because c would be declared outside  your class' scope, your instance is unaware of what its been named in code.

Perhaps if you can provide a broader explanation of what you're trying to accomplish a better solution can be suggested.

OwnerDisplayName: xktybot

Body:
I am doing something like this:

class Class(object):
    def __init__(self):
        self.var=#new instance name string#

How do I make the __ init __ method of my instance to use the instance name string for 'c'? Say in case:

c=Class()

I want c.var equal to 'c'.

Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

c=Class()

Then, suppose:

del c

Later on:

c=Class()

sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

c=Class()

Then, suppose:

del c

Later on:

c=Class()

sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

LastEditorDisplayName: xktybot

OwnerDisplayName: Soviut

ContentLicense: CC BY-SA 2.5


问:
Learning COBOL Without Access to Mainframe
I am a graduate student majoring in Computer Science.  My department teaches the majority of its courses using Java (though I did take one course on system architecture that used C to demonstrate processor scheduling, memory management, etc....but I digress).

I want to learn more about COBOL, but I don't have access to a mainframe system.  Can anyone please recommend a free COBOL compiler for Windows that would enable me to get through some basic COBOL tutorials?

Disclaimer:  yes, I've Googled this already, so hoping for some experienced individuals to give some further info.

Thanks!

答: Try OpenCOBOL http://www.opencobol.org/, it's free, it runs on Windows and Linux and is being actively developed.</p>


问:
Android : why does defining the widgets in this part (i.e MainActivity ) Cause an error
If I define the following lines

```<code>myText =(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
</code>```

in onCreate the program runs smoothly but if I do that in Main Activity then it causes an error.

```<code>import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    myText =(TextView)findViewById(R.id.textView); //error
    button=(Button)findViewById(R.id.button);

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(myText.getVisibility()==View.VISIBLE){

                    myText.setVisibility(View.INVISIBLE);
                }else
                {
                    myText.setVisibility(View.VISIBLE);
                }

            }
        });
    }
}
</code>```

答:
You should move

```<code>myText =(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
</code>```

to onCreate method / after setContentView, otherwise you will get nullPointerException. Initialize happened inside onCreate method.

You have to define the Widget

```<code> TextView myText =(TextView)findViewById(R.id.textView);
 Button button=(Button)findViewById(R.id.button);
</code>```

Body:
If I define the following lines

myText =(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);

in onCreate the program runs smoothly but if I do that in Main Activity then it causes an error.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    myText =(TextView)findViewById(R.id.textView); //error
    button=(Button)findViewById(R.id.button);

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(myText.getVisibility()==View.VISIBLE){

                    myText.setVisibility(View.INVISIBLE);
                }else
                {
                    myText.setVisibility(View.VISIBLE);
                }

            }
        });
    }
}

Body:
You should move

myText =(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);

to onCreate method / after setContentView, otherwise you will get nullPointerException. Initialize happened inside onCreate method.

You have to define the Widget

 TextView myText =(TextView)findViewById(R.id.textView);
 Button button=(Button)findViewById(R.id.button);


问:
Changing the frequency of a signal using Matlab
I want to change the frequency of a given oscillatory signal y(t) using Matlab.

Let's consider a sine signal as an example:

```<code>h = 0.01;         %step width
t = 0:h:2*pi;
y = sin(2*pi*t);
</code>```

This generates a sine signal with a frequency of 1 Hz, assuming t is measured in seconds.

Is it possible to change the frequency of the signal y(t) to an arbitrary frequency of x Hz without using y = sin(2*pi*x*t) (as the actual signal I want to change the frequency of isn't given analytically)?

What I actually want to do is comparing the signal form of signals with different frequencies by changing their frequency to a common one and overlay them. It is important that the different signals can be evaluated at the same time points.

答: Looks like you want to perform frequency shifting. This topic is very old and you can find discussion in many places. E.g. https://www.dsprelated.com/showthread/comp.dsp/9996-1.php</p>

Body:
I want to change the frequency of a given oscillatory signal y(t) using Matlab.

Let's consider a sine signal as an example:

h = 0.01;         %step width
t = 0:h:2*pi;
y = sin(2*pi*t);

This generates a sine signal with a frequency of 1 Hz, assuming t is measured in seconds.

Is it possible to change the frequency of the signal y(t) to an arbitrary frequency of x Hz without using y = sin(2*pi*x*t) (as the actual signal I want to change the frequency of isn't given analytically)?

What I actually want to do is comparing the signal form of signals with different frequencies by changing their frequency to a common one and overlay them. It is important that the different signals can be evaluated at the same time points.


问:
Is there any way to detect lowest point of a letter in javascript?
I've been playing with JS/jQuery recently and I'm trying to make a physical model of letters with gravity etc. For proper collision of a letter with ground, I need to find coordinates of the lowest point of a rotated letter - the one which touches the bottom of the screen at the moment of collision to calculate angles.

I have an idea which oversimplifies it - to create a rectangular hitbox of the letter, which is known. Actually, for some letters like A, which is fairly triangular, one can design custom shaped hitbox, but it is manual and not exact, and implementing triangle in javascript doesn't seem easy.

I don't need the code, just wanted to hear some ideas, the general approach.

Thank you

答:
You want to use canvas, write letter onto it and then inspect pixels positions and do calculus. Dont know the specs but that way not only could you find the lowest point but also a center of mass and an angle which i can see both as relevant for gravity/ricochet calculation.

Additionally, you might want to pay attention to performance based on number of letters you need for your project.


问:
Class Cast Exception when DeSerializing an Object
Overview

I am new to Android development and I am trying to serialize and then deserialize the value of an object but I am getting exception.

Exception

FATAL EXCEPTION: main

java.lang.ClassCastException: java.io.File cannot be cast to com.testingapplication.SchoolNameDetails
com.testingapplication.fragment.HomeFragment$1.onClick(HomeFragment.java:62)

What I tried

SchoolNameDetails class is as follows:

```<code>public class SchoolNameDetails implements Serializable {
private int id;
private String schoolname;
private String level;
private String pkno;
private String nano;
private String ucname;
private String officeno;
private static final long serialVersionUID = 46548923;

public SchoolNameDetails(){}

public SchoolNameDetails(String schoolname, String level, String pkno,String nano, String ucname, String officeno){
    this.schoolname=schoolname;
    this.level=level;
    this.pkno=pkno;
    this.nano=nano;
    this.ucname=ucname;
    this.officeno=officeno;
}

public SchoolNameDetails(int id, String schoolname, String level, String pkno,String nano, String ucname, String officeno){
    this.id=id;
    this.schoolname=schoolname;
    this.level=level;
    this.pkno=pkno;
    this.nano=nano;
    this.ucname=ucname;
    this.officeno=officeno;
}

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getSchoolname() {
    return schoolname;
}
public void setSchoolname(String schoolname) {
    this.schoolname = schoolname;
}
public String getLevel() {
    return level;
}
public void setLevel(String level) {
    this.level = level;
}
public String getPkno() {
    return pkno;
}
public void setPkno(String pkno) {
    this.pkno = pkno;
}
public String getNano() {
    return nano;
}
public void setNano(String nano) {
    this.nano = nano;
}
public String getUcname() {
    return ucname;
}
public void setUcname(String ucname) {
    this.ucname = ucname;
}
public String getOfficeno() {
    return officeno;
}
public void setOfficeno(String officeno) {
    this.officeno = officeno;
}
</code>```

}

and here I am serializing the object

```<code>@Override
protected void onStop() {
    super.onStop();
    SchoolNameDetails details = new SchoolNameDetails();
    details.setSchoolname(t2.getText().toString());
    details.setLevel(t2a.getText().toString());
    details.setPkno(t5.getText().toString());
    details.setNano(t6.getText().toString());
    details.setUcname(t7.getText().toString());
    details.setOfficeno(t8.getText().toString());

    saveObject(details);

}

public void saveObject(SchoolNameDetails d) {
    try
    {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/sdcard/save_object.ser")));
        oos.flush();
        oos.close();
    }
    catch(Exception ex)
    {
        Log.v("Error",ex.getMessage());
        ex.printStackTrace();
    }

}
</code>```

and Here I am deserializing the object in my Fragment class

```<code>@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_home,
            container, false);
    Button b1= (Button) view.findViewById(R.id.button1);
    final TextView t1 = (TextView) view.findViewById(R.id.textView1);
    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SchoolNameDetails details = (SchoolNameDetails)loadSerializedObject(new File("/sdcard/save_object.ser"));
            System.out.println("Name : " + details.getSchoolname());
        }

    });

    return view;
}
public Object loadSerializedObject(File f)
{
    try
    {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
        Object o = ois.readObject();

    }
    catch(Exception ex)
    {
        Log.v("Error : ","" + ex.getMessage());
        ex.printStackTrace();
    }
    return f;
}
</code>```

Now the last return value gives exception. i tried with return null but then it gives null pointer exception.Please Help I am stuck in this for hours and haven't found any solution

答:
First of all change your saveObject method to actually write the object:

```<code>public void saveObject(SchoolNameDetails d) {
    try
    {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/sdcard/save_object.ser")));
        //write to ObjectOutputStream
        oos.writeObject(d);
        oos.flush();
        oos.close();
    }
    catch(Exception ex)
    {
        Log.v("Error",ex.getMessage());
        ex.printStackTrace();
    }
}
</code>```

Next change your loadSerializedObject method to return the object from the input stream:

```<code>public SchoolNameDetails loadSerializedObject(File f)
{
    try
    {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
        SchoolNameDetails o = (SchoolNameDetails ) ois.readObject();
        return o;
    }
    catch(Exception ex)
    {
        Log.v("Error : ","" + ex.getMessage());
        ex.printStackTrace();
    }
    return null;
}
</code>```

Finally in your onClick make sure the object is not null:

```<code>    @Override
    public void onClick(View view) {
        SchoolNameDetails details = loadSerializedObject(new File("/sdcard/save_object.ser"));
        if (details != null) {
            System.out.println("Name : " + details.getSchoolname());
        }
    }
</code>```

Body:
Overview

I am new to Android development and I am trying to serialize and then deserialize the value of an object but I am getting exception.

Exception

FATAL EXCEPTION: main

java.lang.ClassCastException: java.io.File cannot be cast to com.testingapplication.SchoolNameDetails
com.testingapplication.fragment.HomeFragment$1.onClick(HomeFragment.java:62)

What I tried

SchoolNameDetails class is as follows:

public class SchoolNameDetails implements Serializable {
private int id;
private String schoolname;
private String level;
private String pkno;
private String nano;
private String ucname;
private String officeno;
private static final long serialVersionUID = 46548923;

public SchoolNameDetails(){}

public SchoolNameDetails(String schoolname, String level, String pkno,String nano, String ucname, String officeno){
    this.schoolname=schoolname;
    this.level=level;
    this.pkno=pkno;
    this.nano=nano;
    this.ucname=ucname;
    this.officeno=officeno;
}

public SchoolNameDetails(int id, String schoolname, String level, String pkno,String nano, String ucname, String officeno){
    this.id=id;
    this.schoolname=schoolname;
    this.level=level;
    this.pkno=pkno;
    this.nano=nano;
    this.ucname=ucname;
    this.officeno=officeno;
}

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getSchoolname() {
    return schoolname;
}
public void setSchoolname(String schoolname) {
    this.schoolname = schoolname;
}
public String getLevel() {
    return level;
}
public void setLevel(String level) {
    this.level = level;
}
public String getPkno() {
    return pkno;
}
public void setPkno(String pkno) {
    this.pkno = pkno;
}
public String getNano() {
    return nano;
}
public void setNano(String nano) {
    this.nano = nano;
}
public String getUcname() {
    return ucname;
}
public void setUcname(String ucname) {
    this.ucname = ucname;
}
public String getOfficeno() {
    return officeno;
}
public void setOfficeno(String officeno) {
    this.officeno = officeno;
}

}

and here I am serializing the object

@Override
protected void onStop() {
    super.onStop();
    SchoolNameDetails details = new SchoolNameDetails();
    details.setSchoolname(t2.getText().toString());
    details.setLevel(t2a.getText().toString());
    details.setPkno(t5.getText().toString());
    details.setNano(t6.getText().toString());
    details.setUcname(t7.getText().toString());
    details.setOfficeno(t8.getText().toString());

    saveObject(details);

}

public void saveObject(SchoolNameDetails d) {
    try
    {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/sdcard/save_object.ser")));
        oos.flush();
        oos.close();
    }
    catch(Exception ex)
    {
        Log.v("Error",ex.getMessage());
        ex.printStackTrace();
    }

}

and Here I am deserializing the object in my Fragment class

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_home,
            container, false);
    Button b1= (Button) view.findViewById(R.id.button1);
    final TextView t1 = (TextView) view.findViewById(R.id.textView1);
    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SchoolNameDetails details = (SchoolNameDetails)loadSerializedObject(new File("/sdcard/save_object.ser"));
            System.out.println("Name : " + details.getSchoolname());
        }

    });

    return view;
}
public Object loadSerializedObject(File f)
{
    try
    {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
        Object o = ois.readObject();

    }
    catch(Exception ex)
    {
        Log.v("Error : ","" + ex.getMessage());
        ex.printStackTrace();
    }
    return f;
}

Now the last return value gives exception. i tried with return null but then it gives null pointer exception.Please Help I am stuck in this for hours and haven't found any solution

Body:
First of all change your saveObject method to actually write the object:

public void saveObject(SchoolNameDetails d) {
    try
    {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/sdcard/save_object.ser")));
        //write to ObjectOutputStream
        oos.writeObject(d);
        oos.flush();
        oos.close();
    }
    catch(Exception ex)
    {
        Log.v("Error",ex.getMessage());
        ex.printStackTrace();
    }
}

Next change your loadSerializedObject method to return the object from the input stream:

public SchoolNameDetails loadSerializedObject(File f)
{
    try
    {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
        SchoolNameDetails o = (SchoolNameDetails ) ois.readObject();
        return o;
    }
    catch(Exception ex)
    {
        Log.v("Error : ","" + ex.getMessage());
        ex.printStackTrace();
    }
    return null;
}

Finally in your onClick make sure the object is not null:

    @Override
    public void onClick(View view) {
        SchoolNameDetails details = loadSerializedObject(new File("/sdcard/save_object.ser"));
        if (details != null) {
            System.out.println("Name : " + details.getSchoolname());
        }
    }


问:
Reading a string from and to a certain character
I would like to know if it is possible to read a certain string of n-length, from x character to y character without having to split it into smaller pieces.

I have the following string, for a path in AD CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com, and I would like to be able to just read the someName part of it, without splitting by = or , first. How do I achieve that?

Reason is, that I do not have to do group comparison as I am doing it right now:

```<code>SearchResult t1 = search.FindOne();
foreach (string s in t1.Properties["memberof"])
{
    foreach (string g in groups)
    {
        if (s.ToLower().Contains(g.ToLower()))
        {
            // do something
        }
    }
}
</code>```

I would rather make the if clause to equals, but I do not want to always split the above path/groups into an array twice. How do I do that?

答:
Using simple string manipulation with IndexOf and Substring:

```<code>string s = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";

const string prefix = "CN=";
int start = s.IndexOf(prefix);
if (start >= 0)
{
    string value = s.Substring(start + prefix.Length, s.IndexOf(',', start) - prefix.Length);
    Console.WriteLine(value);
}
</code>```

Note that this simple example would fail if the CN= entry was the last in the line (since it’s not terminated by a comma). You could check that first by looking at the return value of the second IndexOf call though.

But in this case, CN= will usually be the first thing anyway.

Body:
I would like to know if it is possible to read a certain string of n-length, from x character to y character without having to split it into smaller pieces.

I have the following string, for a path in AD CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com, and I would like to be able to just read the someName part of it, without splitting by = or , first. How do I achieve that?

Reason is, that I do not have to do group comparison as I am doing it right now:

SearchResult t1 = search.FindOne();
foreach (string s in t1.Properties["memberof"])
{
    foreach (string g in groups)
    {
        if (s.ToLower().Contains(g.ToLower()))
        {
            // do something
        }
    }
}

I would rather make the if clause to equals, but I do not want to always split the above path/groups into an array twice. How do I do that?

Body:
Using simple string manipulation with IndexOf and Substring:

string s = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";

const string prefix = "CN=";
int start = s.IndexOf(prefix);
if (start >= 0)
{
    string value = s.Substring(start + prefix.Length, s.IndexOf(',', start) - prefix.Length);
    Console.WriteLine(value);
}

Note that this simple example would fail if the CN= entry was the last in the line (since it’s not terminated by a comma). You could check that first by looking at the return value of the second IndexOf call though.

But in this case, CN= will usually be the first thing anyway.


问:
Dispatching C++ generated files into srcs and hdrs
In the Bazel official documentation there is an example explaining how to create a Java library built from regular java files and files generated by a :gen_java_srcs rule. I rewrite this code here for ease of reading:

```<code>java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)
</code>```

Now in a C++ perspective, I am in a scenario where the genrule generates two kind of files: .hpp and .cpp:

```<code>genrule(
    name = "gen_cpp_srcs",
    outs = [
        "myFile_1.hpp","myFile_2.hpp",...,"myFile_N.hpp",
        "myFile.cpp","myFile_2.cpp",...,"myFile_N.cpp",
    ],
    ...
)
</code>```

where N is some tens.

My problem/question is: how to write the cc_library rule, with an automatic dispatching of the hpp and cpp files into hdrs and srcs field?

I want something like:

```<code>cc_library(
    name = "mylib",
    srcs = glob(["*.cpp"]) + (howto: .cpp files of [":gen_cpp_srcs"]),
    hdrs = glob(["*.hpp"]) + (howto: .hpp files of [":gen_cpp_srcs"]),
    ...
)
</code>```

Some magic like:

```<code>output_filter(":gen_cpp_srcs","*.cpp")
</code>```

would be perfect, but I do not know enough of Bazel to make it real.

答:
Globs only get expanded when they're passed into rules, so you'll need to write a simple rule. I would package it like this (in a file named filter.bzl):

```<code># The actual rule which does the filtering.
def _do_filter_impl(ctx):
  return struct(
    files = set([f for f in ctx.files.srcs if f.path.endswith(ctx.attr.suffix)]),
  )
_do_filter = rule(
  implementation = _do_filter_impl,
  attrs = {
    "srcs": attr.label_list(
      mandatory = True,
      allow_files = True,
    ),
    "suffix": attr.string(
      mandatory = True,
    ),
  },
)

# A convenient macro to wrap the custom rule and cc_library.
def filtered_cc_library(name, srcs, hdrs, **kwargs):
  _do_filter(
    name = "%s_hdrs" % name,
    visibility = ["//visibility:private"],
    srcs = hdrs,
    suffix = ".hpp",
  )
  _do_filter(
    name = "%s_srcs" % name,
    visibility = ["//visibility:private"],
    srcs = srcs,
    suffix = ".cpp",
  )
  native.cc_library(
    name = name,
    srcs = [ ":%s_srcs" % name ],
    hdrs = [ ":%s_hdrs" % name ],
    **kwargs
  )
</code>```

This is what my demo BUILD file looks like (I changed the globs so they both include *.cpp and *.hpp files; using the label of a genrule will work the same way):

```<code>load("//:filter.bzl", "filtered_cc_library")

filtered_cc_library(
    name = "mylib",
    srcs = glob(["*.*pp"]),
    hdrs = glob(["*.*pp"]),
)
</code>```

This is easy to extend to more sophisticated filtering by changing _do_filter_impl. In particular, changing suffix to an attr.string_list so you can accept multiple C/C++ source/header extensions seems like a good idea.

Body:
In the Bazel official documentation there is an example explaining how to create a Java library built from regular java files and files generated by a :gen_java_srcs rule. I rewrite this code here for ease of reading:

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

Now in a C++ perspective, I am in a scenario where the genrule generates two kind of files: .hpp and .cpp:

genrule(
    name = "gen_cpp_srcs",
    outs = [
        "myFile_1.hpp","myFile_2.hpp",...,"myFile_N.hpp",
        "myFile.cpp","myFile_2.cpp",...,"myFile_N.cpp",
    ],
    ...
)

where N is some tens.

My problem/question is: how to write the cc_library rule, with an automatic dispatching of the hpp and cpp files into hdrs and srcs field?

I want something like:

cc_library(
    name = "mylib",
    srcs = glob(["*.cpp"]) + (howto: .cpp files of [":gen_cpp_srcs"]),
    hdrs = glob(["*.hpp"]) + (howto: .hpp files of [":gen_cpp_srcs"]),
    ...
)

Some magic like:

output_filter(":gen_cpp_srcs","*.cpp")

would be perfect, but I do not know enough of Bazel to make it real.

Body:
Globs only get expanded when they're passed into rules, so you'll need to write a simple rule. I would package it like this (in a file named filter.bzl):

# The actual rule which does the filtering.
def _do_filter_impl(ctx):
  return struct(
    files = set([f for f in ctx.files.srcs if f.path.endswith(ctx.attr.suffix)]),
  )
_do_filter = rule(
  implementation = _do_filter_impl,
  attrs = {
    "srcs": attr.label_list(
      mandatory = True,
      allow_files = True,
    ),
    "suffix": attr.string(
      mandatory = True,
    ),
  },
)

# A convenient macro to wrap the custom rule and cc_library.
def filtered_cc_library(name, srcs, hdrs, **kwargs):
  _do_filter(
    name = "%s_hdrs" % name,
    visibility = ["//visibility:private"],
    srcs = hdrs,
    suffix = ".hpp",
  )
  _do_filter(
    name = "%s_srcs" % name,
    visibility = ["//visibility:private"],
    srcs = srcs,
    suffix = ".cpp",
  )
  native.cc_library(
    name = name,
    srcs = [ ":%s_srcs" % name ],
    hdrs = [ ":%s_hdrs" % name ],
    **kwargs
  )

This is what my demo BUILD file looks like (I changed the globs so they both include *.cpp and *.hpp files; using the label of a genrule will work the same way):

load("//:filter.bzl", "filtered_cc_library")

filtered_cc_library(
    name = "mylib",
    srcs = glob(["*.*pp"]),
    hdrs = glob(["*.*pp"]),
)

This is easy to extend to more sophisticated filtering by changing _do_filter_impl. In particular, changing suffix to an attr.string_list so you can accept multiple C/C++ source/header extensions seems like a good idea.


问:
What CSS properties are likely to cause problems in Internet Explorer?
I designed a web page with lot of CSS properties, and when viewing it in IE its alignment is not so proper compared to all other browsers.

For the next time, what are the CSS properties I should take care with in IE?

Thank you.

答:
Stay clear of using the following, it doesnt play nice in ie.</p>

```<code>display:inline-block
</code>```

Body:
Stay clear of using the following, it doesnt play nice in ie.

display:inline-block