在给定像素数组的情况下用 C 语言实现波纹效果

发布于 2024-12-03 20:07:29 字数 62 浏览 1 评论 0原文

我必须在像素数组上实现波纹效果。每个像素都是代表 ARGB 颜色的 32 位整数。有人对如何开始有什么建议吗?

I have to implement a ripple effect on an array of pixels. Each pixel is a 32 bit integer representing an ARGB color. Does anyone have any suggestions on how to start?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

用心笑 2024-12-10 20:07:29

一般来说,波纹效应是图像的某种失真,其中失真量以“波浪”图案从点到点变化。因此第一个任务是创建一个“深度映射”,为每个像素生成一个数字。直观上,深度图将表示原始像素上方波纹水面的高度。实验的起点可以是

#define X_CENTER 100   // x pixel position of center
#define Y_CENTER 100   // y pixel position of center
#define RADIUS 70      // approximate radius of circular wave train, in pixels
#define WAVELENGTH 10  // wavelength of ripples, in pixels
#define TRAINWIDTH 3.4 // approximate width of wave train, in wavelengths
#define SUPERPHASE 1.5 // phase vel. / group vel. (irrelevant for stills)

// returns a number from -1.0 to 1.0
double depth(int x, int y) {
  double dx = x - X_CENTER ; // or int, if the center coords are ints
  double dy = y - Y_CENTER ;
  double r = (sqrt(dx*dx+dy*dy)-RADIUS)/WAVELENGTH ;
  double k = r - (1-SUPERPHASE)*RADIUS/WAVELENGTH ;
  double a = 1 / (1.0 + (r/TRAINWIDTH)*(r/TRAINWIDTH));
  return a * sin(k*2*PI);
}

当你有了深度图(如果你想要的只是将相同的波纹应用于许多不同的图像,则可以预先计算深度图),你可以选择如何处理它:

  • 使每个像素变亮或变暗按照其深度的比例,
  • 将深度图对角线移动几个像素,并根据移动后的图和未移动的图之间的差异变亮或变暗。
  • 将图像中的每个像素稍微移动一个向量,该向量与每个像素的深度与其(例如)东和南邻居的深度之间的差异成正比。为了获得视觉上令人愉悦的结果,可能需要进行一些平滑或过采样,特别是如果您的基本图像包含清晰的轴平行边缘。

可能需要对这些方法的组合和变化进行一些实验才能大致了解您所期望的效果。

Generally, a ripple effect is some kind of distortion of the image where the amount of distortion varies from point to point in a "wavy" pattern. So the first task is to create a "depth mapping" producing a number for each pixel. Intuitively the depth map will represent the height of a rippled water surface above the original pixels. A starting point for experimentation could be

#define X_CENTER 100   // x pixel position of center
#define Y_CENTER 100   // y pixel position of center
#define RADIUS 70      // approximate radius of circular wave train, in pixels
#define WAVELENGTH 10  // wavelength of ripples, in pixels
#define TRAINWIDTH 3.4 // approximate width of wave train, in wavelengths
#define SUPERPHASE 1.5 // phase vel. / group vel. (irrelevant for stills)

// returns a number from -1.0 to 1.0
double depth(int x, int y) {
  double dx = x - X_CENTER ; // or int, if the center coords are ints
  double dy = y - Y_CENTER ;
  double r = (sqrt(dx*dx+dy*dy)-RADIUS)/WAVELENGTH ;
  double k = r - (1-SUPERPHASE)*RADIUS/WAVELENGTH ;
  double a = 1 / (1.0 + (r/TRAINWIDTH)*(r/TRAINWIDTH));
  return a * sin(k*2*PI);
}

When you have the depth map (which can be precomputed if all you want is to apply the same ripple to many different images), you have various options for what to do with it:

  • lighten or darken each pixel in proportion to its depth
  • shift the depth map a few pixels diagonally, and lighten or darken according to the difference between the shifted and unshifted map.
  • move each pixel slightly in the image, by a vector proportional to the difference between each pixel's depth and that of its (say) east and south neighbors. Some smoothing or oversampling may be necessary for a visually pleasing result especially if your base image contains crisp axis-parallel edges.

It may take some experimentation with combinations and variations of these to approximate your mental picture of the desired effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文