Başka bir tedarikçiden geçiş? Check out our migration guide
Delta PNG çıktı formatı gecikme süresi ve band aralığı konusunda ciddi miktarda tasarruf sağlayabilir ve mobil uygulamalar gibi gecikme süresi ve band aralığı kritik olan senaryolarda özellikle faydalıdır.
Orjinal resimdeki piksellerin istemciye yüklenmiş olması gerekir ve daha sonra sonuç resmini oluşturmak için orjinal resme Delta PNG uygulanır.
Örnek:
778 ×639 piksel
409.048 bayt
110.904 bayt
Bu saç odaklı örnekte bile (ki bu Delta PNG formatı için en kötü senaryodur), kurtarma önemli ölçüdedir: %73
Delta PNG yalnızca normal bir PNG dosyasıdır ve PNGleri okuma kapasitesine sahip herhangi bir yazılım kitaplığı tarafından okunabilmektedir. Normal bir PNG ile karşılaştırıldığında var olan tek fark piksel değerlerinin kendisidir. Arka plan şeffaf siyah olarak 0x00000000 ve ön plan ise şeffaf beyaz olarak 0x00FFFFFF kodlanmıştır. Kısmi şeffaf pikseller kendi gerçek renk değerlerine sahiptir.
| Piksel Türü | Orjinal | Normal PNG | Delta PNG | Çıktı Formatı |
|---|---|---|---|---|
| Ön Plan |
0xFFrrggbb
|
0xFFrrggbb
|
0x00FFFFFF
|
Orjinal |
| Arka Plan |
0xFFrrggbb
|
0x00000000
|
0x00000000
|
Delta PNG |
| Kenar |
0xFFrrggbb
|
0x80rrggbb
|
0x80rrggbb
|
Delta PNG |
Bu, Delta PNG piksel değerlerini deşifre ederken, şeffaf beyaz 0x00FFFFFF ile karşılaştığında Orjinalden gerçek piksel değerini almanız gerektiği anlamına gelir. Diğer piksellerin normal PNG formatıyla aynı değerleri vardır.
Delta PNG formatını deşifre etmek için bir TypeScript kodu örneğini şurda bulabilirsiniz:
export function decodeDeltaPngInPlace(originalPixels: Uint8Array, deltaPngPixels: Uint8Array): Uint8Array {
const N = originalPixels.length / 4; // Array of RGBA values, div 4 to get number of pixels
for (let i = 0; i < N; i++) {
const i4 = i * 4;
const alpha = deltaPngPixels[i4 + 3]; // JavaScript is RGBA, +3 to get alpha
if (alpha == 0) {
const r = deltaPngPixels[i4]; // JavaScript is RGBA, +0 to get red
if (r == 0xFF) {
// Transparent white => foreground => take values from original
deltaPngPixels[i4] = originalPixels[i4];
deltaPngPixels[i4 + 1] = originalPixels[i4 + 1];
deltaPngPixels[i4 + 2] = originalPixels[i4 + 2];
deltaPngPixels[i4 + 3] = originalPixels[i4 + 3];
} // else transparent black => background => keep values
} // else partially transparent => keep values
}
return deltaPngPixels;
}
JavaScript'te resim ve piksel verisi üzerinde işlem yapma konusunda daha fazla bilgi için bakınız Mozilla Developer Network'te yer alan mükemmel Canvas rehberi ile Piksel manipülasyonu .
Resim yükleme kitaplığınızın tamamen şeffaf pikseller için bile piksel değerlerini koruyabilir olması gerekmektedir, ki kitaplıklar normalde bu şekilde çalışmaktadır.
Ancak, örneğin Phyton ve oldukça iyi bilinen OpenCV kitaplığını kullanıyorsanız, cv2.IMREAD_UNCHANGED etiketini kullanmanız ve resmi o şekilde yüklemeniz gerekmektedir: cv2.imread(path, cv2.IMREAD_UNCHANGED). Aksi takdirde, OpenCV tamamen şeffaf piksellerin gerçek piksel değerlerinin üzerine yazar.
Ne yazık ki OpenCV bu etiketi kullandığınızda resimde saklanan hiçbir rotasyon bilgisini uygulamaz. Bizim X-Input-Orientation başlığını geri döndürmemizin nedeni bu; böylece siz bu senaryodaki resme doğru oryantasyonu uygulayabilirsiniz.
Oryantasyonu uygulamak için bir Phyton+OpenCV kodu örneğini burada bulabilirsiniz:
def apply_exif_rotation(im: np.ndarray, orientation: int) -> np.ndarray:
# https://note.nkmk.me/en/python-opencv-numpy-rotate-flip/
if 1 < orientation <= 8:
if 2 == orientation: # TOP-RIGHT, flip left-right, [1, 1] -> [-1, 1]
im = cv2.flip(im, 1)
elif 3 == orientation: # BOTTOM-RIGHT, rotate 180
im = cv2.rotate(im, cv2.ROTATE_180)
elif 4 == orientation: # BOTTOM-LEFT, flip up-down, [1, 1] -> [1, -1]
im = cv2.flip(im, 0)
elif 5 == orientation: # LEFT-TOP, Rotate 90 and flip left-right
im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE)
im = cv2.flip(im, 1)
elif 6 == orientation: # RIGHT-TOP, Rotate 90
im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE)
elif 7 == orientation: # RIGHT-BOTTOM,
im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE)
im = cv2.flip(im, 0)
else: # 8 == orientation: # LEFT-BOTTOM, Rotate 270
im = cv2.rotate(im, cv2.ROTATE_90_COUNTERCLOCKWISE)
return im