Skip to content

Instantly share code, notes, and snippets.

@KzoNag
Created December 2, 2017 08:25
Show Gist options
  • Save KzoNag/0db533c964e9a293d3aca614e5a8025c to your computer and use it in GitHub Desktop.
Save KzoNag/0db533c964e9a293d3aca614e5a8025c to your computer and use it in GitHub Desktop.
VuforiaでImageTargetのサイズでカメラ画像をトリミングする
using UnityEngine;
using Vuforia;
public class ImageTrimmer : MonoBehaviour
{
private ImageTargetBehaviour imageTargetBehaviour;
#if UNITY_EDITOR
private const Image.PIXEL_FORMAT PixcelFormat = Image.PIXEL_FORMAT.RGBA8888;
private const TextureFormat TexFormat = TextureFormat.RGBA32;
#else
private const Image.PIXEL_FORMAT PixcelFormat = Image.PIXEL_FORMAT.RGB888;
private const TextureFormat TexFormat = TextureFormat.RGB24;
#endif
void Start()
{
imageTargetBehaviour = GetComponent<ImageTargetBehaviour>();
CameraDevice.Instance.SetFrameFormat(PixcelFormat, true);
}
public Texture2D Trim()
{
if(imageTargetBehaviour.CurrentStatus != TrackableBehaviour.Status.TRACKED)
{
return null;
}
var image = CameraDevice.Instance.GetCameraImage(PixcelFormat);
if(image == null || !image.IsValid()){ return null; }
var wholeTexture = new Texture2D(image.Width, image.Height, TexFormat, false);
wholeTexture.LoadRawTextureData(image.Pixels);
wholeTexture.Apply();
var fov = CameraDevice.Instance.GetCameraFieldOfViewRads();
var markerSize = imageTargetBehaviour.GetSize();
var position = transform.position; // ARCameraのWorldCenterModeがCAMERA以外の場合は座標変換する必要ありと思われ
// X方向
int startX, width;
GetTrimStartAndLength(fov.x, markerSize.x, position.x, position.z, wholeTexture.width, out startX, out width);
// Y方向
int startY, height;
GetTrimStartAndLength(fov.y, markerSize.y, position.y, position.z, wholeTexture.height, out startY, out height);
// テクスチャの向き・原点を考慮して切り出し開始位置を指定する必要があり
var colors = wholeTexture.GetPixels(wholeTexture.width - startX - width, startY, width, height);
var trimTexture = new Texture2D(width, height, TexFormat, false);
trimTexture.SetPixels(colors);
trimTexture.Apply();
return trimTexture;
}
private void GetTrimStartAndLength(float fov, float worldMarkerSize, float worldPosXY, float worldPosZ, int textureSize, out int start, out int length)
{
float tan = Mathf.Tan(fov / 2);
float worldCameraViewSize = 2 * worldPosZ * tan;
float a = 0.5f - ((worldPosXY + worldMarkerSize * 0.5f) / worldCameraViewSize);
float b = worldMarkerSize / worldCameraViewSize;
float c = 0.5f + ((worldPosXY - worldMarkerSize * 0.5f) / worldCameraViewSize);
start = (int)(textureSize * a);
length = (int)(textureSize * b);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment