emptygif
زبان: فارسی

کوچک‌ترین GIF شفاف 43 بایت است.

کل فایل همین است. روی هر بایتی بزنید تا ببینید چه کار می‌کند، بعد فایل را کپی یا دانلود کنید، مستقیم لینکش کنید یا از کد خودتان سرو کنید.

GIF 43 بایتی، بزرگ‌نمایی‌شده: یک پیکسل شفاف
0000
0010
0020
دانلود 1×1.gif

R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

هر بایت چه می‌کند

GIF دنباله‌ای از بلوک‌هاست. این فایل هفت بلوک دارد و هر رنگ در این صفحه به یکی از آن‌ها تعلق دارد. برای خواندن، یک بایت یا بلوک را انتخاب کنید. اعداد به‌صورت little-endian ذخیره می‌شوند: بایت کم‌ارزش اول می‌آید، پس 01 00 یعنی 1.

بایت‌هافیلدمعنی
هدر به دیکودر می‌گوید این فایل GIF است و باید منتظر کدام نسخه از فرمت باشد.
47 49 46امضاحروف ASCII «GIF». هر فایل GIF با آن‌ها شروع می‌شود.
38 39 61نسخه«89a». برای شفافیت 89a لازم است؛ 87a افزونه کنترل گرافیک ندارد.
توصیفگر صفحه منطقی اندازه بوم و نحوه تنظیم جدول رنگ آن.
01 00عرض بوم۱ px.
01 00ارتفاع بوم۱ px.
80فلگ‌های فشردهچهار تنظیم در یک بایت جا شده‌اند. بیت بالایی می‌گوید پس از آن جدول رنگ سراسری می‌آید؛ سه بیت آخر اندازه‌اش را مشخص می‌کنند.
00اندیس رنگ پس‌زمینهورودی ۰ پالت. مرورگرها آن را نادیده می‌گیرند و آنچه پشت تصویر است را نشان می‌دهند.
00نسبت ابعاد پیکسل0 یعنی پیکسل‌های مربعی، بدون هیچ اصلاحی.
جدول رنگ سراسری پالت. پیکسل‌ها به‌جای رنگ، یک اندیس در این فهرست ذخیره می‌کنند.
FF FF FFورودی پالتقرمز، سبز و آبی، هرکدام یک بایت: #ffffff. دو ورودی کوچک‌ترین جدولی است که یک GIF می‌تواند داشته باشد.
00 00 00ورودی پالتقرمز، سبز و آبی، هرکدام یک بایت: #000000. دو ورودی کوچک‌ترین جدولی است که یک GIF می‌تواند داشته باشد.
افزونه کنترل گرافیک بلوکی اختیاری که در GIF89a اضافه شد. اینجا ورودی 0 پالت را شفاف می‌کند.
21معرف افزونه0x21 («!») آغاز یک بلوک افزونه را اعلام می‌کند.
F9برچسب کنترل گرافیک0xF9 می‌گوید این افزونه، افزونه کنترل گرافیک است.
04اندازه بلوکپس از آن ۴ بایت تنظیمات می‌آید.
01فلگ‌های فشردهپایین‌ترین بیت، فلگ شفافیت است. روشن است، پس اندیس شفاف زیر به کار می‌رود.
00 00تأخیر۰ صدم ثانیه. فقط برای انیمیشن‌ها اهمیت دارد.
00اندیس رنگ شفافورودی ۰ پالت کاملاً شفاف رسم می‌شود.
00پایان‌دهنده بلوکیک زیربلوک با طول صفر که بلوک را می‌بندد.
توصیفگر تصویر جای تصویر روی بوم و اندازه آن.
2Cجداکننده تصویر0x2C («,») یک تصویر را آغاز می‌کند.
00 00چپتصویر ۰ px دورتر از لبه چپ بوم شروع می‌شود.
00 00بالاتصویر ۰ px دورتر از لبه بالای بوم شروع می‌شود.
01 00عرض تصویر۱ px.
01 00ارتفاع تصویر۱ px.
00فلگ‌های فشردهبدون جدول رنگ محلی، بدون interlace. تصویر از پالت سراسری استفاده می‌کند.
داده تصویر پیکسل‌ها، فشرده‌شده با LZW و تقسیم‌شده به زیربلوک‌هایی تا سقف 255 بایت.
02حداقل اندازه کد LZW۲، پس کدهای فشرده با عرض ۳ بیت شروع می‌شوند.
02اندازه زیربلوکپس از آن ۲ بایت داده فشرده می‌آید.
44 01پیکسل‌های فشردهکدهای LZW از پایین‌ترین بیت به بالا بسته‌بندی شده‌اند. پایین‌تر ببینید چطور دیکود می‌شوند.
00پایان‌دهنده بلوکیک زیربلوک با طول صفر که بلوک را می‌بندد.
پایان‌نما یک بایت که پایان فایل را مشخص می‌کند.
3Bپایان‌نما0x3B («;») فایل را تمام می‌کند.

درون بایت‌های فشرده

هرکدام از این سه بایت چند تنظیم کوچک را در خود نگه می‌دارد. بیت 7 چپ‌ترین بیت است.

توصیفگر صفحه منطقی 0x80
1جدول رنگ سراسری وجود دارد
000وضوح رنگ
0پالت بر اساس اهمیت مرتب شده
000اندازه جدول: 2^(n+1) ورودی
افزونه کنترل گرافیک 0x01
000رزرو‌شده
000روش دورریزی (disposal)
0انتظار برای ورودی کاربر
1شفافیت روشن
توصیفگر تصویر 0x00
0جدول رنگ محلی وجود دارد
0Interlace شده
0پالت بر اساس اهمیت مرتب شده
00رزرو‌شده
000اندازه جدول محلی

دو بایت چطور یک پیکسل را نگه می‌دارند

با حداقل اندازه کد 2، دیکودر کدهای 3 بیتی می‌خواند. کد 4 جدول را پاک می‌کند، کد 5 تصویر را تمام می‌کند و کدهای 0 تا 3 ورودی‌های پالت‌اند. بایت‌های 44 01 از پایین‌ترین بیت به بالا خوانده می‌شوند:

0x44 010001000x01 00000001

  1. 001100 = 4پاک‌سازی: شروع با جدولی تازه
  2. 000000 = 0پیکسل: ورودی ۰ پالت
  3. 101101 = 5پایان تصویر
  4. 0000000 بیت‌های پرکننده بلااستفاده

تصاویر بزرگ‌تر هم از همین ترفند استفاده می‌کنند: هر کد جدید نماینده رشته‌ای است که یک پیکسل از قبلی بلندتر است، پس یک GIF شفاف 1000×1000 فقط ۱٬۷۴۳ بایت جا می‌گیرد.

کوچک‌تر هم می‌شود؟

بله، اگر بخش‌هایی را حذف کنید که دیکودرها نبودشان را تحمل می‌کنند. هر نسخه را به سه موتور مرورگر و به Pillow دادیم و آنچه رسم کردند را ثبت کردیم.

اندازهنسخهChromiumFirefoxWebKitPillow
۴۳فایل استاندارد این صفحه.شفافشفافشفافشفاف
۴۲بدون بایت پایان‌نما. دیکودرها در هر صورت در پایان داده متوقف می‌شوند.شفافشفافشفافشفاف
۳۷اصلاً پالت ندارد. باز هم معتبر است: مشخصات فنی به دیکودرها اجازه می‌دهد پالت خودشان را به کار ببرند، و اندیس 0 در هر صورت شفاف است.شفافشفافشفافشفاف
۳۶بدون پالت و بدون پایان‌نما.شفافشفافشفافشفاف
۳۵بدون بلوک شفافیت: پیکسل با رنگ 0 پالت، یعنی سفید، رسم می‌شود.سفیدسفیدسفیدسفید
۳۵فرمت سال 1987. هیچ راهی برای شفاف علامت‌زدن یک رنگ ندارد.سفیدسفیدسفیدسفید
۳۴بلوک شفافیت هست، اما پیکسل فشرده‌ای نیست.شفافشفافشفافخطا
۳۳همان، بدون پایان‌نما.شفافشفافشفافخطا
۲۹بدون پالت و بدون شفافیت. هر موتور رنگ خودش را انتخاب می‌کند.سیاهسفیدشفافسیاه
۲۶تصویری که اصلاً داده فشرده ندارد.شفافشفافشفافخطا
۱۴فقط هدر، اندازه بوم و پایان‌نما. هیچ تصویری در آن نیست.شفافخطاشفافخطا

وقتی باید همه‌جا کار کند، از 43 بایت استفاده کنید. 37 بایت هنوز GIF معتبر است و در همه موتورهایی که آزمودیم شفاف بود. کمتر از آن به سهل‌گیری دیکودر وابسته می‌شوید، و فایل 29 بایتی نشان می‌دهد موتورها چقدر با هم اختلاف دارند.

بررسی‌شده در ۱ مهر ۱۴۰۵ با Chromium 153.0.8010.12, Firefox 155.0, WebKit 26.6, Pillow 12.2.0.

در هر اندازه‌ای بسازید

شفاف یا تک‌رنگ، از 1×1 تا 65535×65535. در مرورگر خودتان ساخته می‌شود؛ چیزی آپلود نمی‌شود.

پرکردن
اندازه‌های رایج

1×1 · ۴۳ بایت

دانلود GIF

از استک خودتان سرو کنید

۱۷۳ قطعه‌کد آماده اجرا. مال خودتان را انتخاب کنید: هرکدام روی مسیری که انتخاب می‌کنید با پاسخ image/gif جواب می‌دهد. اگر بالاتر اندازه یا رنگ را تغییر داده‌اید، قطعه‌کدها از همان GIF استفاده می‌کنند.

Elixir, Erlang & Gleam

Express JavaScript

نصب
npm i express
فایل
server.mjs
اجرا
node server.mjs
import express from 'express';

const GIF = Buffer.from('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', 'base64');

const app = express();

app.get('/pixel.gif', (req, res) => {
  res.set('Cache-Control', 'no-store');
  res.type('gif').send(GIF);
});

app.listen(8080);

این قطعه‌کد را اجرا کردیم و بایت‌هایی را که برگرداند مقایسه کردیم. باز کردن صفحه

کاربردها

  • پیکسل‌های ردیابی و beaconها: سرور درخواست را لاگ می‌کند و با کوچک‌ترین تصویر معتبر پاسخ می‌دهد.
  • جانگهدار برای تصاویر lazy-load، تا تگ img پیش از رسیدن منبع واقعی معتبر باشد.
  • فاصله‌گذارهای با اندازه ثابت در ایمیل HTML، جایی که پشتیبانی از CSS ناقص است.
  • تست‌ها و mockهایی که به یک تصویر واقعی نیاز دارند بدون اینکه فایل تصویری همراهشان باشد.

پیکسل‌های ردیابی کمتر از آنچه به نظر می‌رسند قابل اعتمادند

وقتی Mail Privacy Protection روشن است، Apple Mail تصاویر راه دور را از طریق یک پراکسی پیش‌بارگذاری می‌کند، پس ممکن است یک «باز شدن» اصلاً کار یک انسان نبوده باشد. Gmail هم تصاویر را از طریق پراکسی خودش می‌گیرد و کش می‌کند. بسیاری از کلاینت‌ها به‌طور پیش‌فرض تصاویر راه دور را مسدود می‌کنند. برای آنالیتیکس صفحه، navigator.sendBeacon() یا یک پاسخ 204 No Content اغلب از تصویر مناسب‌تر است.

پرسش‌ها

چرا به آن خالی می‌گویند وقتی یک پیکسل دارد؟
یک GIF باید دست‌کم یک پیکسل داشته باشد. این یکی 1×1 است و تنها رنگش شفاف علامت خورده، پس چیزی دیده نمی‌شود.
آیا فایل 43 بایتی معتبر است؟
بله. دقیقاً از مشخصات GIF89a پیروی می‌کند و همه موتورهای جدول بالا آن را شفاف رسم می‌کنند.
چرا GIF و نه PNG یا WebP؟
از کوچک‌ترین PNG شفاف هم کوچک‌تر است، و هر مرورگر، کلاینت ایمیل و کتابخانه تصویر از 35 سال گذشته تا امروز می‌تواند آن را بخواند.
از data URI استفاده کنم یا فایل؟
data URI یک درخواست صرفه‌جویی می‌کند و برای جانگهدارها و CSS مناسب است. وقتی خودِ درخواست هدف است، مثل پیکسل‌های ردیابی، به فایل یا endpoint نیاز دارید.
کدام Content-Type را بفرستم؟
image/gif. اگر همه درخواست‌ها باید به سرور شما برسند، Cache-Control: no-store را اضافه کنید.