如何实现非中心式图像Bloat效果?求Python/Node.js/PHP解决方案
实现非中心原点的图像Bloat效果
当然可以实现!这种效果的核心逻辑是基于自定义原点计算像素距离,再根据距离调整像素的偏移/放大程度,而非固定使用图像中心。下面给你三个语言的可行解决方案:
Python 方案(使用PIL库)
先确保安装依赖:pip install pillow
原理:遍历每个像素,计算其到自定义原点的距离,根据距离缩放像素偏移量,模拟膨胀效果。
from PIL import Image import math def bloat_image_custom_origin(input_path, output_path, origin=(100, 150), strength=0.1): img = Image.open(input_path) width, height = img.size pixels = img.load() new_img = Image.new(img.mode, (width, height)) new_pixels = new_img.load() for x in range(width): for y in range(height): # 计算当前像素到自定义原点的距离 dx = x - origin[0] dy = y - origin[1] distance = math.hypot(dx, dy) # 根据距离计算偏移量,距离越远偏移越大(膨胀效果) offset_x = dx * strength * (distance / max(width, height)) offset_y = dy * strength * (distance / max(width, height)) # 确保新位置不超出图像范围 new_x = int(x + offset_x) new_y = int(y + offset_y) new_x = max(0, min(new_x, width-1)) new_y = max(0, min(new_y, height-1)) new_pixels[x, y] = pixels[new_x, new_y] new_img.save(output_path) # 使用示例 bloat_image_custom_origin("input.jpg", "output_python.jpg", origin=(200, 200), strength=0.2)
Node.js 方案(使用sharp库)
先安装依赖:npm install sharp
sharp是高性能图像处理库,这里通过操作像素缓冲区实现效果:
const sharp = require('sharp'); async function bloatImageCustomOrigin(inputPath, outputPath, origin = {x: 100, y: 150}, strength = 0.1) { const img = await sharp(inputPath).raw().toBuffer({resolveWithObject: true}); const {data, info} = img; const {width, height, channels} = info; const newData = Buffer.alloc(data.length); for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const dx = x - origin.x; const dy = y - origin.y; const distance = Math.hypot(dx, dy); const offsetX = dx * strength * (distance / Math.max(width, height)); const offsetY = dy * strength * (distance / Math.max(width, height)); let newX = Math.round(x + offsetX); let newY = Math.round(y + offsetY); newX = Math.max(0, Math.min(newX, width - 1)); newY = Math.max(0, Math.min(newY, height - 1)); // 复制像素数据到新位置 const srcIdx = (newY * width + newX) * channels; const destIdx = (y * width + x) * channels; for (let c = 0; c < channels; c++) { newData[destIdx + c] = data[srcIdx + c]; } } } await sharp(newData, {raw: {width, height, channels}}).toFile(outputPath); } // 使用示例 bloatImageCustomOrigin('input.jpg', 'output_node.jpg', {x: 200, y: 200}, 0.2) .then(() => console.log('处理完成')) .catch(err => console.error(err));
PHP 方案(使用GD库)
确保PHP已启用GD扩展(大部分环境默认开启):
function bloatImageCustomOrigin($inputPath, $outputPath, $origin = [100, 150], $strength = 0.1) { $img = imagecreatefromjpeg($inputPath); $width = imagesx($img); $height = imagesy($img); $newImg = imagecreatetruecolor($width, $height); for ($x = 0; $x < $width; $x++) { for ($y = 0; $y < $height; $y++) { $dx = $x - $origin[0]; $dy = $y - $origin[1]; $distance = hypot($dx, $dy); $offsetX = $dx * $strength * ($distance / max($width, $height)); $offsetY = $dy * $strength * ($distance / max($width, $height)); $newX = (int)($x + $offsetX); $newY = (int)($y + $offsetY); $newX = max(0, min($newX, $width - 1)); $newY = max(0, min($newY, $height - 1)); $color = imagecolorat($img, $newX, $newY); imagesetpixel($newImg, $x, $y, $color); } } imagejpeg($newImg, $outputPath); imagedestroy($img); imagedestroy($newImg); } // 使用示例 bloatImageCustomOrigin('input.jpg', 'output_php.jpg', [200, 200], 0.2);
效果调整小技巧
- 修改
origin参数可设置任意非中心的膨胀原点 - 调整
strength参数控制膨胀强度,值越大效果越明显 - 如果需要更细腻的效果,可以优化距离计算的权重公式,比如加入非线性的距离映射
内容的提问来源于stack exchange,提问作者Алекс Кирсанов
相关产品推荐
相关产品推荐

