Equirect to image

Equirect to image

by jinam yu

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/3.1.0/async.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
    <form class="p-4">
        <div class="form-group">
            <label>이미지 URL을 입력해 보세요.</label>
            <div class="input-group mb-3">

                <input type="text" class="form-control" v-model="source" />
                <div class="input-group-append">
                    <div class="btn-group mr-2" role="group">
                        <button type="button" class="btn btn-primary" @click="convert">Convert</button>
                    </div>
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="card">
                <div class="container-fluid py-3">
                  <img :src="source" style="width: 100%;" />
                </div>
                <div class="container-fluid">
                    <div class="row p-2">
                        <div class="col-4 p-2" v-for="(item, index) in images" :key="index">
                            <img :src="item" alt="" style="width: 100%;" />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </form>
</div>

CSS

html, body {
  background-color: #f8f9fa;
}

Vue

class Equirect {
	clamp(v, lo, hi) {
		return Math.min(hi, Math.max(lo, v));
	}
	srgbToLinear(v) {
		const component = +v * (1.0 / 255.0);
		return component * component;
	}
	linearToSRGB(v) {
		return (Math.sqrt(v) * 255.0) | 0;
	}
	transform(inPixels, face, facePixels) {
		const opts = {
			flipTheta: false,
			interpolation: 'bilinear',
		};
		let thetaFlip = opts.flipTheta ? -1 : 1;
		let edge = facePixels.width | 0;

		let inWidth = inPixels.width | 0;
		let inHeight = inPixels.height | 0;
		let inData = inPixels.data;

		let smoothNearest = opts.interpolation === 'nearest';

		let faceData = facePixels.data;
		let faceWidth = facePixels.width | 0;
		let faceHeight = facePixels.height | 0;

		let iFaceWidth2 = 2.0 / faceWidth;
		let iFaceHeight2 = 2.0 / faceHeight;

		for (let j = 0; j < faceHeight; ++j) {
			for (let i = 0; i < faceWidth; ++i) {
				let a = iFaceWidth2 * i;
				let b = iFaceHeight2 * j;
				let outPos = (i + j * edge) << 2;
				let x = 0.0,
					y = 0.0,
					z = 0.0;
				// @@NOTE: Tried using explicit matrices for this and didn't see any
				switch (face) {
					case 0:
						x = 1.0 - a;
						y = 1.0;
						z = 1.0 - b;
						break; // right  (+x)
					case 1:
						x = a - 1.0;
						y = -1.0;
						z = 1.0 - b;
						break; // left   (-x)
					case 2:
						x = b - 1.0;
						y = a - 1.0;
						z = 1.0;
						break; // top    (+y)
					case 3:
						x = 1.0 - b;
						y = a - 1.0;
						z = -1.0;
						break; // bottom (-y)
					case 4:
						x = 1.0;
						y = a - 1.0;
						z = 1.0 - b;
						break; // front  (+z)
					case 5:
						x = -1.0;
						y = 1.0 - a;
						z = 1.0 - b;
						break; // back   (-z)
				}

				let theta = thetaFlip * Math.atan2(y, x);
				let rad = Math.sqrt(x * x + y * y);
				let phi = Math.atan2(z, rad);

				let uf = (2.0 * (inWidth / 4) * (theta + Math.PI)) / Math.PI;
				let vf = (2.0 * (inWidth / 4) * (Math.PI / 2 - phi)) / Math.PI;
				let ui = Math.floor(uf) | 0,
					vi = Math.floor(vf) |...