Created
June 22, 2018 05:13
-
-
Save hexagit/0ee3e0c65eeabed4fa95cad8a32bc6fd to your computer and use it in GitHub Desktop.
バイリニア法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
public partial class Bitmap | |
{ | |
private struct BilinearInterpolator | |
{ | |
public float ratioX; | |
public float ratioY; | |
public Color c00; | |
public Color c01; | |
public Color c10; | |
public Color c11; | |
public Color interpolate() | |
{ | |
var invereseX = 1.0f - ratioX; | |
var invereseY = 1.0f - ratioY; | |
// 4点で線形補間 | |
return invereseX * (invereseY * c00 + ratioY * c01) + ratioX * (invereseY * c10 + ratioY * c11); | |
} | |
} | |
private Bitmap resizeBilinear(uint width, uint height) | |
{ | |
var bitmap = new Bitmap(width, height); | |
// スケール | |
var scaleX = (float)width / _width; | |
var scaleY = (float)height / _height; | |
// 単位を元画像の座標系に変換 | |
var unitX = 1.0f / scaleX; | |
var unitY = 1.0f / scaleY; | |
// 基準点から4点を決定するオフセット | |
var offsetX = 1; | |
var offsetY = 1; | |
// 1ピクセル幅を考慮した座標の補正 | |
var correctionX = unitX * 0.5f; | |
var correctionY = unitY * 0.5f; | |
// 縮小のときは選択する4点の範囲を拡大 | |
if(unitX > 1.0f) { | |
offsetX = (int)unitX; | |
} | |
if(unitY > 1.0f) { | |
offsetY = (int)unitY; | |
} | |
parallelFor(0, (int)bitmap._height, y => { | |
for(int x = 0; x < bitmap._width; ++x) { | |
// 元画像の座標系に変換 | |
var srcX = unitX * x + correctionX; | |
var srcY = unitY * y + correctionY; | |
// 指定座標を囲む4点のうち左上の点の座標 | |
var baseX = (int)srcX; | |
var baseY = (int)srcY; | |
bitmap[x, y] = interpolateBilinear(baseX, baseY, offsetX, offsetY, srcX, srcY); | |
} | |
}); | |
return bitmap; | |
} | |
private Color interpolateBilinear(int baseX, int baseY, int offsetX, int offsetY, float x, float y) | |
{ | |
var interpolator = new BilinearInterpolator() { | |
// 4点内で正規化された座標 | |
ratioX = (x - baseX) / offsetX, | |
ratioY = (y - baseY) / offsetY, | |
// 4点の色取得 | |
c00 = get(baseX, baseY), | |
c01 = get(baseX, baseY + offsetY), | |
c10 = get(baseX + offsetX, baseY), | |
c11 = get(baseX + offsetX, baseY + offsetY), | |
}; | |
return interpolator.interpolate(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment