پی ڈی ایف فائلوں کا استعمال عام طور پر پریزنٹیشنز، اسکرپٹس، رپورٹس، کورس کے مواد، مزاحیہ صفحات اور دیگر بصری دستاویزات کے اشتراک کے لیے کیا جاتا ہے۔ تاہم، صفحہ کے لحاظ سے ایک طویل پی ڈی ایف صفحہ کا جائزہ لینے میں وقت لگ سکتا ہے۔ اس میں وقت لگ سکتا ہے، خاص طور پر اگر آپ کو مناظر، سلائیڈز یا بصری مواد کی پوری ترتیب کو سمجھنے کی ضرورت ہو۔
اسٹوری بورڈ اس معلومات کا جائزہ لینے کے لیے ایک زیادہ منظم طریقہ فراہم کرتے ہیں۔ ہر صفحہ کو انفرادی طور پر کھولنے کے بجائے، صارف منتخب پی ڈی ایف صفحات کو متعدد پینلز کے ساتھ ایک شیٹ میں ترتیب دے سکتے ہیں۔ ہر پینل میں صفحہ نمبر، کیپشن، اور اصل صفحہ کا بصری پیش نظارہ شامل ہو سکتا ہے۔
اس ٹیوٹوریل میں ہم دیکھیں گے کہ جاوا اسکرپٹ، PDF.js، اور PDF-lib کا استعمال کرتے ہوئے براؤزر پر مبنی PDF اسٹوری بورڈ جنریٹر کیسے بنایا جائے۔
یہ ایپلیکیشن موجودہ پی ڈی ایف سے صفحات لیتی ہے اور انہیں پرنٹ ایبل اسٹوری بورڈ شیٹ میں ترتیب دیتی ہے۔ صارفین مختلف ترتیبوں میں سے انتخاب کر سکتے ہیں، منتخب کر سکتے ہیں کہ کون سے صفحات کو شامل کرنا ہے، کیپشن شامل کرنا ہے، ظاہری شکل کو اپنی مرضی کے مطابق بنانا، نتائج کا پیش نظارہ کرنا، اور مکمل شدہ اسٹوری بورڈ ڈاؤن لوڈ کرنا ہے۔
ایپلیکیشن براہ راست آپ کے براؤزر میں چلتی ہے۔ اپ لوڈ کردہ پی ڈی ایف ویب سائٹ سرور پر اپ لوڈ کرنے کے بجائے مقامی طور پر پروسیس کیے جاتے ہیں۔
آئیے مرحلہ وار عمل درآمد کرتے ہیں، بشمول پی ڈی ایف کو پیش کرنا، صفحات کا انتخاب کرنا، کیپشنز پر کارروائی کرنا، ترتیب کا حساب لگانا، پیش نظارہ بنانا، اور فائل کو برآمد کرنا۔
ہم کیا احاطہ کریں گے:
پی ڈی ایف اسٹوری بورڈ جنریٹر کیا ہے؟
پی ڈی ایف اسٹوری بورڈ جنریٹر موجودہ پی ڈی ایف سے منتخب صفحات کو ساختی بصری شیٹس میں تبدیل کرتا ہے۔
مثال کے طور پر، فرض کریں کہ آپ کے پاس پی ڈی ایف ہے جس میں 20 پریزنٹیشن سلائیڈز ہیں۔ تمام 20 سلائیڈوں کو الگ الگ شیئر کرنے کے بجائے، آپ انہیں تین کالموں اور دو قطاروں فی شیٹ کے ساتھ اسٹوری بورڈ میں ترتیب دے سکتے ہیں۔
ہر پینل اصل پی ڈی ایف صفحہ کا ایک چھوٹا ورژن دکھاتا ہے۔ آپ نمبر یا لیبل بھی شامل کر سکتے ہیں اور ان کے نیچے ایک مختصر تفصیل لکھ سکتے ہیں۔
مندرجہ ذیل معاملات میں بھی یہی طریقہ کارآمد ہو سکتا ہے:
- پریزنٹیشن سلائیڈز کا جائزہ لیں۔
- مزاحیہ صفحہ کی صفائی۔
- ویڈیو منظر کی منصوبہ بندی.
- ایک بصری اسکرپٹ تیار کیا جا رہا ہے۔
- اسکین شدہ دستاویز کا جائزہ لیا جا رہا ہے۔
- پرنٹ ایبل تربیتی مواد بنائیں۔
- تخلیقی منصوبوں کے لیے صفحہ ترتیب کو منظم کریں۔
ایپلیکیشن نئے مناظر نہیں بناتی اور نہ ہی تصویریں کھینچتی ہے۔ موجودہ پی ڈی ایف صفحات کو اسٹوری بورڈ لے آؤٹ میں ترتیب دیں۔
درخواست کی اہم خصوصیات
کوئی بھی کوڈ لکھنے سے پہلے، آئیے اس فنکشنلٹی کو سمجھیں جسے ہم لاگو کرنے جا رہے ہیں۔
1. پی ڈی ایف اپ لوڈ کریں۔
صارفین اپنے ڈیوائس سے پی ڈی ایف منتخب کر سکتے ہیں یا اسے گھسیٹ کر اپ لوڈ ایریا میں چھوڑ سکتے ہیں۔
2. مختلف اسٹوری بورڈ لے آؤٹ
یہ ایپلیکیشن تین ترتیب کو سپورٹ کرتی ہے:
- گرڈ: صفحوں کو قطاروں اور کالموں میں ترتیب دیتا ہے۔
- نوٹ کے ساتھ پینل: صفحہ پینل کے آگے نوٹ لکھنے کے لیے جگہ فراہم کرتا ہے۔
- فلم اسٹریپ: صفحات کو فلمی پٹی کے انداز میں ترتیب دیں۔
3. صفحات منتخب کریں اور آرڈر کریں۔
صارفین اسٹوری بورڈ میں ڈسپلے کرنے کے لیے پی ڈی ایف پیجز کو منتخب کر سکتے ہیں۔ آپ اصل پی ڈی ایف آرڈر پر عمل کرنے کے بجائے اپنی مرضی کے مطابق آرڈر بھی بتا سکتے ہیں۔
4. کیپشن
صارف دستی طور پر کیپشن درج کر سکتے ہیں، خالی کیپشن کو پُر کرنے کے لیے نکالے گئے پی ڈی ایف صفحہ کا متن استعمال کر سکتے ہیں، یا سکین کیے گئے صفحات سے متن پڑھنے کے لیے OCR کا استعمال کر سکتے ہیں۔
5. حسب ضرورت
صارف کاغذ کے سائز، واقفیت، کالموں اور قطاروں کی تعداد، پینل لیبل، شیٹ کا رنگ، کیپشن فونٹ، ٹیکسٹ سائز، وقفہ کاری، اور پینل فریم کو اپنی مرضی کے مطابق بنا سکتے ہیں۔
6. ریئل ٹائم پیش نظارہ
ایپلیکیشن اسٹوری بورڈ شیٹ کا پیش نظارہ بناتی ہے۔ صارفین فائنل آؤٹ پٹ ڈاؤن لوڈ کرنے سے پہلے انتظامات کا جائزہ لے سکتے ہیں۔
7. مختلف برآمدی فارمیٹس
صارفین اپنے کام کو مندرجہ ذیل طور پر برآمد کر سکتے ہیں:
- پی ڈی ایف اسٹوری بورڈ۔
- PNG اسٹوری بورڈ شیٹ۔
- زپ فائل جس میں صفحہ کی انفرادی تصاویر شامل ہیں۔
پی ڈی ایف ایکسپورٹ جب ممکن ہو تو صفحہ کے اصل مواد کو ویکٹر کے طور پر محفوظ کرکے کرکرا متن اور گرافکس کو محفوظ رکھنے میں مدد کرتا ہے۔
براؤزر پر مبنی ورک فلو کو سمجھیں۔
درخواست ایک سادہ عمل کی پیروی کرتی ہے۔
- صارفین پی ڈی ایف فائل منتخب کرتے ہیں یا اسے اپ لوڈ ایریا میں چھوڑ دیتے ہیں۔
- PDF.js دستاویز کو لوڈ کرتا ہے اور صفحہ کو رینڈر کرتا ہے۔
- ایپلیکیشن صفحہ کا پیش نظارہ اور کیپشن فیلڈ دکھاتی ہے۔
- صارفین صفحات منتخب کرتے ہیں، اپنی ترتیب کو تبدیل کرتے ہیں، اور کیپشن درج کرتے ہیں۔
- صارفین اسٹوری بورڈ لے آؤٹ اور ظاہری شکل کو ترتیب دیتے ہیں۔
- JavaScript ہر پینل کی پوزیشن اور سائز کا حساب لگاتا ہے۔
- آپ کی منتخب کردہ ترتیبات کی عکاسی کرنے کے لیے پیش نظارہ اپ ڈیٹس۔
- PDF-lib اور براؤزر کینوس کے فنکشنز کو درخواست کردہ آؤٹ پٹ تیار کرنے کے لیے استعمال کیا جاتا ہے۔
- براؤزر مکمل فائل کو ڈاؤن لوڈ کرتا ہے۔
پی ڈی ایف اپ لوڈ ورک اسپیس
پینلز اور کیپشنز

بورڈ کی ترتیبات اور پیش نظارہ

آخری اسٹوری بورڈ کا پیش نظارہ

پی ڈی ایف ڈاؤن لوڈ کیا گیا۔

پروجیکٹ کی ترتیبات
JavaScript کے فنکشنز لکھنے سے پہلے، آپ کو یہ سمجھنا ہوگا کہ آپ کی ایپلیکیشن کی ساخت کیسے ہے۔
پی ڈی ایف اسٹوری بورڈ جنریٹر ایچ ٹی ایم ایل، سی ایس ایس اور جاوا اسکرپٹ کو یکجا کرتا ہے۔ ایچ ٹی ایم ایل انٹرفیس فراہم کرتا ہے، سی ایس ایس ورک اسپیس اور اسٹوری بورڈ شیٹس کی ظاہری شکل کو کنٹرول کرتا ہے، اور جاوا اسکرپٹ پی ڈی ایف پروسیسنگ، صفحہ کے پیش نظارہ، کیپشن، ترتیب کے حساب کتاب، اور ڈاؤن لوڈنگ کو ہینڈل کرتا ہے۔
اسٹینڈ لون ڈویلپمنٹ پروجیکٹ کے لیے، آپ اپنی فائلوں کو اس طرح ترتیب دے سکتے ہیں:
pdf-storyboard-generator/
├── index.html
├── style.css
├── script.js
└── assets/
کہ index.html فائل میں اپلوڈ ایریا، پیج پینلز، کیپشن فیلڈز، بورڈ سیٹنگز اور پیش نظارہ سمیت ایپلیکیشن کا ڈھانچہ شامل ہے۔
کہ style.css فائلیں آپ کی درخواست کی ظاہری شکل کو کنٹرول کرتی ہیں۔ ورک اسپیس، پینل گرڈ، فارم کنٹرولز، بٹن، پیش نظارہ ایریا، اور ریسپانسیو لے آؤٹ کی وضاحت کریں۔
کہ script.js فائل میں بنیادی ایپلیکیشن منطق شامل ہے۔ پی ڈی ایف دستاویزات لوڈ کریں، صفحات پیش کریں، کیپشنز کا نظم کریں، OCR درخواستوں پر کارروائی کریں، اسٹوری بورڈ لے آؤٹ کا حساب لگائیں، اور ڈاؤن لوڈ کے قابل فائلیں بنائیں۔
کہ assets ڈائریکٹری آپ کے پروجیکٹ کے لیے درکار اضافی مقامی وسائل رکھ سکتی ہے۔
موجودہ AllInOneTools کے نفاذ میں، یہ اجزاء آپ کی ویب سائٹ کے ٹولز پیج میں چار علیحدہ فائلوں کے طور پر تقسیم کرنے کے بجائے ضم کیے جاتے ہیں۔ ذمہ داریوں کی وہی علیحدگی اب بھی لاگو ہوتی ہے۔
استعمال شدہ لائبریریاں
ایپلیکیشن اپنے پی ڈی ایف اور امیج پروسیسنگ ورک فلو کے لیے تین اہم جاوا اسکرپٹ لائبریریوں یا براؤزر ٹیکنالوجیز کا استعمال کرتی ہے۔
1. PDF.js
ہم PDF.js کو پی ڈی ایف دستاویز کھولنے اور اس صفحہ کو براؤزر میں رینڈر کرنے کے لیے استعمال کریں گے۔
یہ JavaScript کو انفرادی صفحہ تک رسائی حاصل کرنے، اس کے سائز کو بازیافت کرنے، ایک ویو پورٹ بنانے اور صفحہ کے مواد کو HTML کینوس پر کھینچنے کی اجازت دیتا ہے۔
اس پروجیکٹ کے لیے، PDF.js اصل PDF صفحات کا جائزہ لینے کے لیے ذمہ دار ہے۔
ایپلیکیشن صفحہ کو بازیافت کرنے اور اسے مطلوبہ سائز پر رینڈر کرنے کے لیے PDF.js دستاویز API کا استعمال کرتی ہے۔ یہ ضروری ہے کیونکہ صارف مکمل شیٹ ڈاؤن لوڈ کرنے سے پہلے اسٹوری بورڈ کو ہر منتخب صفحہ کی بصری نمائندگی دکھانی چاہیے۔
2. PDF-lib
ہم PDF-lib استعمال کریں گے، جو حتمی PDF دستاویز بنانے کے لیے استعمال ہوتا ہے۔
PDF.js اور PDF-lib کی مختلف ذمہ داریاں ہیں۔ PDF.js ماخذ دستاویز کو پڑھتا اور پیش کرتا ہے، جبکہ PDF-lib ایک نیا اسٹوری بورڈ PDF بناتا ہے۔
ایپلیکیشن آؤٹ پٹ پیج بنانے کے لیے PDF-lib کا استعمال کرتی ہے، اگر ممکن ہو تو اصل پی ڈی ایف پیج کو ایمبیڈ کرتی ہے، اور مکمل شدہ اسٹوری بورڈ عناصر کو اس صفحہ پر رکھتی ہے۔
اصل PDF صفحات کو ویکٹر مواد کے طور پر رکھنے سے ٹیکسٹ اور لائن کے معیار کو برقرار رکھنے میں مدد ملتی ہے جب صارف برآمد شدہ دستاویز کو بڑا یا پرنٹ کرتے ہیں۔ نفاذ پاس ورڈ سے محفوظ پی ڈی ایف کے لیے راسٹر پر مبنی فال بیک کا بھی استعمال کرتا ہے جو باقاعدہ پی ڈی ایف ایمبیڈ پاتھ کے ذریعے لوڈ نہیں کیے جا سکتے۔
3. Tesseract.js
یہ لائبریری اختیاری آپٹیکل کریکٹر ریکگنیشن (OCR) فراہم کرتی ہے۔
تمام پی ڈی ایف میں قابل انتخاب متن نہیں ہوتا ہے۔ مثال کے طور پر، اسکین شدہ دستاویز میں اصل ٹیکسٹ ڈیٹا کے بجائے پرنٹ شدہ صفحہ کی تصویر ہوسکتی ہے۔
جب صارف OCR آپشن کو منتخب کرتا ہے، تو ایپلیکیشن Tesseract.js اور اس کا انگریزی ڈیٹا لوڈ کرتی ہے۔ اس کے بعد یہ اہل اسکین شدہ صفحات پر کارروائی کرتا ہے اور کیپشن کے لیے متن نکالنے کی کوشش کرتا ہے۔
OCR اختیاری ہے، لہذا صارفین کو OCR انجن کو لوڈ کرنے کی ضرورت نہیں ہے اگر وہ PDF صفحات کو ترتیب دینا چاہتے ہیں اور دستی طور پر کیپشن لکھنا چاہتے ہیں۔
مندرجہ ذیل مثال سے پتہ چلتا ہے کہ کس طرح اسٹینڈ اسٹون پروجیکٹ میں CDN اسکرپٹ کے ذریعے لائبریری شامل ہوسکتی ہے۔
پروڈکشن ایپلی کیشنز کے لیے، لائبریری ورژن کا استعمال کریں جس کا آپ نے تجربہ کیا ہے اور آپ کے منتخب کردہ PDF.js بلڈ کے مطابق ایک مماثل PDF.js ورکر فائل کو ترتیب دیں۔
یہ لائبریریاں ایک ساتھ کیوں کام کرتی ہیں۔
ہر لائبریری کی الگ الگ ذمہ داریاں ہیں۔
PDF.js سورس پی ڈی ایف کو پڑھتا ہے اور اس کے صفحات پیش کرتا ہے۔ Tesseract.js سکین شدہ صفحات سے متن کو منتخب طور پر نکالتا ہے۔ PDF-lib حتمی اسٹوری بورڈ پی ڈی ایف تیار کرتا ہے۔
JavaScript ان آپریشنز کو جوڑتا ہے اور یوزر انٹرفیس کا انتظام کرتا ہے۔
یہ علیحدگی درخواست کو سمجھنے اور برقرار رکھنے میں آسان بناتی ہے۔ اس کے علاوہ، کسی ایسے کام کے لیے ایک لائبریری کا استعمال نہ کریں جسے دوسری لائبریری کے ذریعے بہتر طریقے سے ہینڈل کیا جائے۔
اپنا HTML ورک اسپیس تیار کریں۔
پورے اسٹوری بورڈ ورک فلو کو سپورٹ کرنے کے لیے، انٹرفیس کو متعدد شعبوں کی ضرورت ہوتی ہے۔
اپ لوڈ ایریا اصل پی ڈی ایف قبول کرتا ہے۔ پینل ایریا پیش کردہ صفحہ اور کیپشن فیلڈز دکھاتا ہے۔ بورڈ کی ترتیبات کے علاقے میں ترتیب اور ظاہری کنٹرول شامل ہیں۔ آخر میں، پیش نظارہ کا علاقہ تخلیق کردہ اسٹوری بورڈ شیٹ کو دکھاتا ہے۔
آسان HTML ڈھانچہ مندرجہ ذیل ہے:
ایک مثالی ڈھانچہ جو مرکزی انٹرفیس کے علاقوں کو ظاہر کرتا ہے۔ حقیقی دنیا کی ایپلی کیشنز میں اضافی کنٹرولز، قابل رسائی خصوصیات، اور مختلف کاموں کے لیے عناصر شامل ہیں۔
کہ aiot-sb کنٹینرز آپ کی ایپلی کیشنز کے لیے ایک مشترکہ جڑ فراہم کرتے ہیں۔ JavaScript پوری ویب سائٹ کو تلاش کیے بغیر متعلقہ انٹرفیس عناصر کو تلاش کرنے کے لیے اس روٹ کا استعمال کر سکتا ہے۔
کلیدی DOM عناصر کو منتخب کریں۔
اس سے پہلے کہ JavaScript صارف کے اعمال کا جواب دے، اسے ایک انٹرفیس عنصر کے حوالے کی ضرورت ہے۔
ایپلیکیشن روٹ کنٹینر کو تلاش کرکے اور یہ جانچنے سے شروع ہوتی ہے کہ آیا ابتداء پہلے ہی انجام پا چکی ہے۔
var root = document.getElementById("aiot-sb");
if (!root || root.getAttribute("data-aiot-sb-ready")) {
return;
}
root.setAttribute("data-aiot-sb-ready", "1");
اگر اسکرپٹ کو ایک سے زیادہ بار چلایا جاتا ہے تو یہ ایپلیکیشن کو دوبارہ شروع کرنے سے روک دے گا۔
نفاذ ایپلی کیشن کے اندر عناصر کو تلاش کرنے کے لیے چھوٹے مددگاروں کا استعمال کرتا ہے۔
function q(selector) {
return root.querySelector(selector);
}
مثال کے طور پر، q('[data-act="browse"]') پی ڈی ایف فائل چننے والے کو کھولنے کے لیے استعمال ہونے والا بٹن تلاش کریں۔
اگر آپ کی ویب سائٹ میں دوسرے ٹولز یا انٹرفیس کے اجزاء شامل ہیں تو روٹ کے لیے مخصوص مددگاروں کا استعمال آپ کے ایپلیکیشن کوڈ کو منظم رکھنے میں بھی مدد کر سکتا ہے۔
اہم کنفیگریشن اقدار کی وضاحت کریں۔
آپ کی ایپلیکیشن کو لے آؤٹ اور آؤٹ پٹ سیٹنگز کے لیے کچھ مشترکہ کنفیگریشن ویلیوز کی ضرورت ہے۔
مثال کے طور پر، معاون کاغذ کے سائز اور فونٹ فیملیز کی وضاحت کریں۔
var MM = 72 / 25.4;
var PAPERS = {
a4: [595.28, 841.89],
letter: [612, 792],
a3: [841.89, 1190.55],
slide: [405, 720]
};
var PAPER_NAMES = {
a4: "A4",
letter: "Letter",
a3: "A3",
slide: "16:9 slide"
};
پی ڈی ایف صفحہ کے سائز کو عام طور پر پوائنٹس میں ظاہر کیا جاتا ہے، جبکہ کچھ سٹوری بورڈ سپیسنگ سیٹنگز کو ملی میٹر میں سمجھنا آسان ہوتا ہے۔ کہ MM تبادلوں کی قدریں آپ کو ان اکائیوں کے درمیان تبدیل کرنے میں مدد کرتی ہیں۔
کہ PAPERS آبجیکٹ دستیاب صفحہ کے سائز کو محفوظ کرتا ہے۔ آپ کی ایپلیکیشن ہر اسٹوری بورڈ شیٹ کے سائز کا حساب لگاتے وقت ان اقدار کو استعمال کرسکتی ہے۔
کہ PAPER_NAMES آبجیکٹ اپنی ترتیبات کے لیے پڑھنے کے قابل لیبل فراہم کرتے ہیں۔
ایپلی کیشن کیپشنز اور دیگر متن کے لیے فونٹ فیملیز کی بھی وضاحت کرتی ہے۔
var FONTS = {
sans: "Arial, 'Helvetica Neue', Helvetica, sans-serif",
serif: "Georgia, 'Times New Roman', serif",
mono: "'Courier New', Courier, monospace",
hand: "'Segoe Print', 'Bradley Hand', cursive"
};
یہ اقدار اسٹوری بورڈ پیش کرنے والے کو پورے کوڈ میں فونٹ کی تعریفیں دہرائے بغیر متن کے مختلف انداز استعمال کرنے کی اجازت دیتی ہیں۔
درخواست کی حالت کو سمجھیں۔
ایپلیکیشن کو فی الحال لوڈ شدہ پی ڈی ایف، اس کے صفحات، کیپشنز، منتخب ترتیب، اور برآمد کے عمل کے بارے میں معلومات کو یاد رکھنا چاہیے۔
پوری ایپلی کیشن میں تقسیم کردہ انفرادی متغیرات پر انحصار کرنے کے بجائے، عمل درآمد گروپ معلومات کو مشترکہ ریاستی اشیاء میں شامل کرتے ہیں۔
مثال کے طور پر، ایپلی کیشن معلومات کو ٹریک کرتی ہے جیسے:
- یہ ایک بھری ہوئی پی ڈی ایف دستاویز ہے۔
- اصل پی ڈی ایف بائٹس۔
- موجودہ فائل کا نام۔
- صفحہ کیپشن۔
- صفحہ کا پیش نظارہ ڈیٹا۔
- لوڈ اور برآمد کی حیثیت۔
- اگر OCR فعال ہے، تو یہ OCR کارکن ہے۔
- منسوخ کریں اور ٹوکن لوڈ کریں۔
ایک حقیقی نفاذ ان اقدار کو ایپلی کیشن کی حالت کے اندر منظم کرے گا اور رینڈرنگ اور ایکسپورٹ فنکشنز میں ان کا استعمال کرے گا۔
یہ خاص طور پر اس وقت اہم ہوتا ہے جب صارفین کیپشنز یا لے آؤٹ سیٹنگز تبدیل کرتے ہیں۔ ایپلی کیشن کو یہ جاننے کی ضرورت ہے کہ کون سی قدریں تبدیل ہوئی ہیں تاکہ اسٹوری بورڈ کے پیش نظارہ کو ماخذ دستاویز کو غیر ضروری دوبارہ کھولے بغیر اپ ڈیٹ کیا جا سکے۔
پی ڈی ایف اپ لوڈ کریں۔
پہلا قدم یہ ہے کہ صارفین کو اپنے ڈیوائس پر پی ڈی ایف منتخب کرنے کی اجازت دی جائے۔ پی ڈی ایف اسٹوری بورڈ جنریٹر دو طریقوں کو سپورٹ کرتا ہے: فائل چننے والے کے ذریعے فائلوں کو منتخب کرنا یا انہیں گھسیٹ کر اپ لوڈ ایریا میں چھوڑنا۔
فائل ان پٹ درج ذیل ایچ ٹی ایم ایل کا استعمال کرتا ہے:
آئیے سمجھتے ہیں۔ accept سے منسوب:
application/pdfپی ڈی ایف فائل کی MIME قسم۔.pdfیہ فائل کی توسیع ہے۔
MIME قسم (ملٹی پرپز انٹرنیٹ میل ایکسٹینشن ٹائپ) فائل کی قسم کی شناخت کرتی ہے۔ براؤزر MIME اقسام کا استعمال کرتے ہیں یہ بیان کرنے کے لیے کہ فائل میں کس قسم کا مواد ہے۔ مثال کے طور پر، application/pdf پی ڈی ایف دستاویزات کی شناخت کریں۔
ایپلیکیشن MIME قسم اور فائل کے نام کی توسیع دونوں کو چیک کرتی ہے۔ یہ مفید ہے کیونکہ کچھ براؤزر یا آپریٹنگ سسٹم منتخب فائل کے لیے خالی یا غلط MIME قسم فراہم کر سکتے ہیں۔
ایک حقیقی درخواست میں، ہم درج ذیل مددگار استعمال کریں گے:
function isPdf(file) {
return file.type === 'application/pdf' ||
/.pdf$/i.test(file.name || '');
}
پہلی شرط فائل کی MIME قسم کو چیک کرتی ہے۔ دوسرا چیک کرتا ہے کہ آیا فائل کا نام ختم ہوتا ہے۔ .pdf. کہ i جھنڈا توسیعی چیکنگ کو کیس غیر حساس بناتا ہے، لہذا فائل کے نام جیسے document.PDF کی بھی اجازت ہے۔
تصدیق کے بعد، اپ لوڈ کے دونوں طریقے یکساں طور پر استعمال کیے جاتے ہیں۔ handleFiles() فنکشن ابتدائی مراحل درج ذیل ہیں:
function handleFiles(list, password) {
var all = Array.prototype.slice.call(list || []);
ui.input.value="";
if (!all.length) {
return Promise.resolve();
}
var file = all.filter(isPdf)[0];
if (!file) {
toast("That isn't a PDF. Choose a PDF file.", 'error');
return Promise.resolve();
}
var note = all.length > 1
? ' Only ' + file.name + ' was opened; a storyboard uses one PDF.'
: '';
var token = ++state.loadToken;
var hadDoc = !!state.doc;
var task, bytes;
if (hadDoc) {
ui.fileMeta.textContent="Opening " + file.name + '…';
}
setStatus('Opening ' + file.name + '…', true);
// The remaining function loads and processes the selected PDF.
}
یہ فنکشن فائلوں کی فراہم کردہ فہرست کو ایک صف میں تبدیل کرتا ہے اور پہلی درست پی ڈی ایف کو منتخب کرتا ہے۔ اگر کوئی درست پی ڈی ایف نہیں ملتا ہے، تو یہ ایک غلطی کا پیغام دکھاتا ہے اور رک جاتا ہے۔
کہ loadToken قدر ایپلی کیشن کو موجودہ لوڈ آپریشن کو پچھلے آپریشنز سے ممتاز کرنے میں مدد کرتی ہے۔ یہ اس وقت اہم ہوتا ہے جب کوئی صارف دوسری دستاویز کا انتخاب کرتا ہے جب کہ پچھلی دستاویز پر کارروائی جاری ہے۔
اگلا، ایپلیکیشن پی ڈی ایف لائبریری کے دستیاب ہونے تک انتظار کرتی ہے اور منتخب فائل کو پڑھتی ہے۔
return engine().then(function () {
return file.arrayBuffer();
}).then(function (buf) {
bytes = buf;
var opts = {
data: new Uint8Array(buf.slice(0))
};
if (password) {
opts.password = password;
}
task = window.pdfjsLib.getDocument(pdfjsOptions(opts));
return task.promise;
});
کہ file.arrayBuffer() یہ طریقہ پی ڈی ایف کو براؤزر میموری میں پڑھتا ہے۔ ایپلیکیشن ڈیٹا کو اس میں تبدیل کرتی ہے: Uint8Array اسے PDF.js کے ذریعے بھیجیں: getDocument().
اگر پاس ورڈ فراہم کیا جاتا ہے، تو دستاویز کو کھولنے سے پہلے اسے PDF.js کے اختیارات میں شامل کر دیا جائے گا۔
یہ پی ڈی ایف صفحات کی پیمائش کرتا ہے، چیک کرتا ہے کہ آیا اصل صفحہ کو ویکٹر کے طور پر سرایت کیا جا سکتا ہے، ایپلی کیشن کی حالت کو اپ ڈیٹ کرتا ہے، ورک اسپیس دکھاتا ہے، وغیرہ۔
اس کا مطلب ہے کہ منتخب کردہ پی ڈی ایف پر آپ کے براؤزر کے ذریعے کارروائی کی جائے گی۔ اسے ویب سائٹ کے سرور پر اپ لوڈ نہیں کیا گیا ہے۔
PDF.js کا استعمال کرتے ہوئے پی ڈی ایف لوڈ کریں۔
جب ایک فائل کا انتخاب کیا جاتا ہے، تو ایپلیکیشن اس کے مواد کو پڑھتی ہے اور ڈیٹا کو PDF.js میں منتقل کرتی ہے۔
PDF.js لوڈ کرنے کا عمل ایک دستاویز آبجیکٹ واپس کرتا ہے۔ یہ آبجیکٹ دستاویز کے صفحات اور میٹا ڈیٹا تک رسائی فراہم کرتا ہے۔
ایک حقیقی ایپلی کیشن میں، PDF.js کو فائل لوڈ کرنے کے عمل میں شروع کیا جاتا ہے۔ ایپلیکیشن پہلے پی ڈی ایف لائبریری کے لوڈ ہونے کا انتظار کرتی ہے، منتخب فائل کو پڑھتی ہے، اور پھر اس ڈیٹا کو PDF.js میں منتقل کرتی ہے۔
return engine().then(function () {
return file.arrayBuffer();
}).then(function (buf) {
bytes = buf;
var opts = {
data: new Uint8Array(buf.slice(0))
};
if (password) {
opts.password = password;
}
task = window.pdfjsLib.getDocument(pdfjsOptions(opts));
return task.promise;
});
کہ engine() یہ فیچر چیک کرتا ہے کہ آیا ضروری پی ڈی ایف لائبریریاں پروسیسنگ شروع ہونے سے پہلے دستیاب ہیں۔ ایپلیکیشن پھر استعمال کرتی ہے: file.arrayBuffer() منتخب کردہ پی ڈی ایف براؤزر میموری میں لوڈ ہو جائے گی۔
کہ Uint8Array کنسٹرکٹر فائل ڈیٹا کو ایک فارمیٹ میں تبدیل کرتا ہے جسے PDF.js پروسیس کر سکتا ہے۔ اگر صارف پاس ورڈ فراہم کرتا ہے تو دستاویز کو کھولنے سے پہلے پاس ورڈ PDF.js کے اختیارات میں شامل کر دیا جاتا ہے۔
کہ getDocument() طریقہ پی ڈی ایف لوڈنگ کا عمل شروع کرتا ہے اور task.promise یہ اس وقت حل ہو جاتا ہے جب PDF.js دستاویز کو کامیابی سے کھولتا ہے۔
نتیجہ خیز دستاویز آبجیکٹ PDF صفحات اور میٹا ڈیٹا تک رسائی فراہم کرتا ہے۔ ایپلیکیشن اس دستاویز کو بعد کے کاموں کے لیے محفوظ کرتی ہے جیسے صفحات کی پیمائش کرنا، متن نکالنا، پیش نظارہ کرنا، اور اسٹوری بورڈ بنانا۔
پی ڈی ایف صفحہ کی پیمائش
کسی صفحہ کو اسٹوری بورڈ پینل میں ترتیب دینے سے پہلے، آپ کی درخواست کو اس کا سائز جاننے کی ضرورت ہے۔
پی ڈی ایف دستاویزات میں مختلف سائز اور واقفیت کے صفحات شامل ہوسکتے ہیں۔ ہر صفحہ کی پیمائش کرنے سے لے آؤٹ انجن کو پینل کے اندر صفحہ کو درست طریقے سے فٹ کرنے میں مدد ملتی ہے۔
ایک حقیقی درخواست میں آپ استعمال کریں گے: pageFacts() ایک خصوصیت جو ہر صفحے کی پیمائش کرتی ہے اور بڑے پی ڈی ایف پر کارروائی کرتے ہوئے وقتا فوقتا انٹرفیس کو اپ ڈیٹ کرتی ہے۔
async function pageFacts(doc, token) {
var sizes = [];
for (var n = 1; n <= doc.numPages; n++) {
if (token !== state.loadToken) {
return null;
}
if (n % 25 === 0) {
setStatus(
'Measuring pages: ' + n + ' of ' + doc.numPages + '…',
true
);
await nextFrame();
}
var p = await doc.getPage(n);
var vp = p.getViewport({ scale: 1 });
sizes.push([vp.width, vp.height]);
}
return sizes;
}
فنکشن ایک خالی جگہ بنا کر شروع ہوتا ہے۔ sizes صف پھر استعمال کرتے ہوئے تمام صفحات کے ذریعے اعادہ کریں: doc.numPages ہر صفحہ تلاش کریں۔ doc.getPage(n).
کہ getViewport({ scale: 1 }) یہ طریقہ صفحہ کو اس کے اصل سائز پر ماپتا ہے۔ یہ فنکشن نتیجے میں چوڑائی اور اونچائی کو سیٹ کرتا ہے۔ sizes صف
کہ token پیرامیٹرز پرانے لوڈ آپریشنز کو جاری رکھنے سے روکنے میں مدد کرتے ہیں۔ اگر موجودہ ٹوکن مزید مماثل نہیں ہے۔ state.loadTokenفنکشن رک جاتا ہے اور واپس آتا ہے۔ null.
بڑی PDFs کے لیے، ایپلیکیشن ہر 25 صفحات پر لوڈ اسٹیٹس کو اپ ڈیٹ اور کال کرتی ہے۔ nextFrame() یہ براؤزر کو اپنے انٹرفیس کو اپ ڈیٹ کرنے کا موقع فراہم کرتا ہے۔
آخر میں، فنکشن تمام ناپے ہوئے صفحات کے سائز پر مشتمل ایک صف لوٹاتا ہے۔ یہ پیمائشیں بعد میں اسٹوری بورڈ لے آؤٹ کے حساب کتاب میں استعمال ہوتی ہیں۔
کینوس پر پی ڈی ایف صفحات پیش کریں۔
اگلا کام پی ڈی ایف صفحات کو ورک اسپیس میں ڈسپلے کرنا ہے۔
PDF.js انفرادی صفحات کو HTML کینوس پر رینڈر کر سکتا ہے۔ کینوس ایک بصری نمائندگی فراہم کرتا ہے جسے صفحہ کارڈز اور اسٹوری بورڈز کا پیش نظارہ کرنے کے لیے استعمال کیا جا سکتا ہے۔
بنیادی رینڈرنگ کی خصوصیات میں شامل ہیں:
async function renderPage(n, w, h) {
var page = await state.doc.getPage(n);
var b = page.getViewport({ scale: 1 });
var vp = page.getViewport({
scale: Math.min(w / b.width, h / b.height)
});
var c = document.createElement('canvas');
c.width = Math.max(1, Math.round(vp.width));
c.height = Math.max(1, Math.round(vp.height));
var g = c.getContext('2d');
g.fillStyle="#FFFFFF";
g.fillRect(0, 0, c.width, c.height);
await page.render({
canvas: c,
canvasContext: g,
viewport: vp
}).promise;
return c;
}
یہ فنکشن تین پیرامیٹرز کو قبول کرتا ہے۔ n پی ڈی ایف صفحہ نمبر ہے، w اور h پیش نظارہ کے لیے دستیاب چوڑائی اور اونچائی کی وضاحت کرتا ہے۔
سب سے پہلے state.doc.getPage(n) مطلوبہ پی ڈی ایف صفحہ بازیافت کرتا ہے۔ اس کے بعد فنکشن صفحہ کا اصل سائز حاصل کرنے کے لیے سائز 1 کا ویو پورٹ بناتا ہے۔
اگلا، Math.min(w / b.width, h / b.height) تناسب کو تبدیل کیے بغیر دستیاب جگہ کے اندر صفحہ کو فٹ کرنے کے لیے پیمانے کا حساب لگاتا ہے۔
یہ فنکشن ایک HTML کینوس بناتا ہے اور حسابی ویوپورٹ سائز کا استعمال کرتے ہوئے چوڑائی اور اونچائی سیٹ کرتا ہے۔ پی ڈی ایف پیج کو رینڈر کرنے سے پہلے کینوس کو سفید سے بھرتا ہے۔
آخر کار page.render() کینوس پر ایک صفحہ بنائیں۔ یہ فنکشن رینڈرنگ کے مکمل ہونے کا انتظار کرتا ہے اور صفحہ کے پیش نظارہ اور اسٹوری بورڈنگ کے لیے استعمال کرنے کے لیے ایک مکمل کینوس واپس کرتا ہے۔

پیش کردہ صفحہ کے پیش نظاروں کو دوبارہ استعمال کریں۔
ایک ہی پی ڈی ایف پیج کو بار بار رینڈر کرنے سے پروسیسنگ کا غیر ضروری وقت ضائع ہو سکتا ہے۔ مثال کے طور پر، ایک صفحہ کارڈ کے پیش منظر کے لیے ایک بار پیش کیا جا سکتا ہے اور اسٹوری بورڈ کا پیش نظارہ اپ ڈیٹ ہونے پر دوبارہ پیش کیا جا سکتا ہے۔
آپ کی ایپلیکیشن صفحہ تصویر کیش کا استعمال کرتی ہے تاکہ پہلے پیش کیے گئے کینوس کو دوبارہ استعمال کیا جا سکے۔
var picCache = new Map();
// For the preview: reuse a page picture when one at least as big is already made.
async function cachedPic(n, w, h) {
var got = picCache.get(n);
if (got && got.w >= w * 0.92) {
picCache.delete(n);
picCache.set(n, got);
return got.c;
}
var c = await renderPage(
n,
Math.ceil(w * 1.15),
Math.ceil(h * 1.15)
);
picCache.set(n, { c: c, w: c.width });
while (picCache.size > 60) {
var old = picCache.keys().next().value;
picCache.get(old).c.width = 1;
picCache.delete(old);
}
return c;
}
ایپلیکیشن پیش کردہ صفحہ کے پیش نظارہ کو JavaScript کے بطور محفوظ کرتی ہے۔ Map بلایا picCache. ہر آئٹم میں پیش کردہ کینوس اور اس کی چوڑائی ہوتی ہے۔
جب cachedPic() جب بلایا جاتا ہے، تو یہ سب سے پہلے یہ دیکھنے کے لیے چیک کرتا ہے کہ آیا درخواست کردہ صفحہ کے لیے کیش شدہ تصویر موجود ہے یا نہیں۔ اگر کیش شدہ تصویر درخواست کردہ چوڑائی کے 92% سے زیادہ ہے، تو ایپلیکیشن صفحہ کو دوبارہ پیش کرنے کے بجائے اسے دوبارہ استعمال کرتی ہے۔
یہ فنکشن دوبارہ استعمال شدہ اشیاء کو نقشے کے آخر تک لے جاتا ہے۔ یہ آپ کی ایپلیکیشن کو حال ہی میں استعمال شدہ پیش نظارہ کا استعمال جاری رکھنے کی اجازت دیتا ہے۔
اگر مناسب طریقے سے کیش شدہ تصویر دستیاب نہیں ہے تو، فنکشن کال کرتا ہے: renderPage() نیا کینوس بنانے کے لیے، صفحہ کو مطلوبہ چوڑائی اور اونچائی سے 1.15 گنا پر رینڈر کریں تاکہ پیش نظارہ میں اضافی ریزولوشن فراہم کیا جا سکے۔
میموری کے استعمال کو کنٹرول کرنے کے لیے، کیش 60 اندراجات تک محدود ہے۔ اگر اس حد سے تجاوز کیا جاتا ہے تو، قدیم ترین آئٹمز کو ہٹا دیا جاتا ہے اور کینوس کی چوڑائی کو کم کر کے 1 کر دیا جاتا ہے، جس سے ڈرائنگ کے وسائل خالی ہوتے ہیں۔
یہ کیشنگ اپروچ میموری کے استعمال کو کنٹرول کرتے ہوئے غیر ضروری پی ڈی ایف رینڈرنگ کو روکتا ہے، خاص طور پر جب صارفین طویل دستاویزات کے ساتھ کام کرتے ہیں۔
پی ڈی ایف صفحات سے متن پڑھیں
اسٹوری بورڈ جنریٹر تین طریقوں سے کیپشن بنا سکتا ہے:
- صارفین دستی طور پر کیپشن لکھتے ہیں۔
- ایپلیکیشن پی ڈی ایف سے متن نکالتی ہے۔
- OCR اسکین شدہ صفحات پر متن پڑھتا ہے۔
منتخب متن کے ساتھ PDFs کے لیے PDF.js فراہم کرتا ہے: getTextContent() طریقہ
ایک حقیقی درخواست میں آپ استعمال کریں گے: readTexts() ایک خصوصیت جو بھری ہوئی پی ڈی ایف کے تمام صفحات سے متن نکالتی اور محفوظ کرتی ہے۔
async function readTexts(token) {
var doc = state.doc, out = [];
for (var n = 1; n <= doc.numPages; n++) {
if (token !== state.loadToken) {
return;
}
try {
var tc = await (await doc.getPage(n)).getTextContent();
out.push(tc.items.map(function (it) {
return (it.str || '') + (it.hasEOL ? 'n' : '');
}).join(''));
} catch (e) {
out.push('');
}
if (n % 20 === 0) {
await nextFrame();
}
}
if (token !== state.loadToken) {
return;
}
state.texts = out;
refreshTags(board());
}
یہ خصوصیت پی ڈی ایف دستاویزات تک رسائی کے ذریعے شروع ہوتی ہے state.doc اور یہ اس طرح ایک خالی صف بناتا ہے: out نکالے گئے متن کو محفوظ کریں۔
پھر تمام صفحات کے ذریعے اعادہ کریں اور کال کریں۔ getTextContent() ٹیکسٹ آئٹمز تلاش کریں۔ کہ map() یہ طریقہ ہر آئٹم کے متن کو ایک سٹرنگ میں جوڑتا ہے۔ مزید برآں، PDF.js آئٹمز لائن کے اختتام کی نشاندہی کرتے وقت ایک نئی لائن کا اضافہ کرتے ہیں۔ hasEOL.
اگر کسی صفحہ کے لیے متن نکالنا ناکام ہوجاتا ہے، تو فنکشن پورے عمل کو روکنے کے بجائے نتائج میں ایک خالی سٹرنگ جوڑتا ہے۔
کہ token چیک پچھلے پی ڈی ایف لوڈ آپریشنز کو موجودہ ایپلیکیشن کی حالت کو اپ ڈیٹ کرنے سے روکتا ہے۔ یہ فنکشن بھی کال کرتا ہے: nextFrame() ہر 20 صفحات پر، ہم براؤزر کو ان کے انٹرفیس کو اپ ڈیٹ کرنے کا موقع دیتے ہیں۔
تمام صفحات پر کارروائی کرنے کے بعد، نکالا ہوا متن ہے۔ state.texts. درخواست پھر کال کرتی ہے: refreshTags(board()) ورک اسپیس میں دکھائے گئے صفحہ کی معلومات کو اپ ڈیٹ کرتا ہے۔
یہ محفوظ کردہ متن بعد میں استعمال کیا جائے گا جب صارف خود بخود خالی سرخیوں کو بھرنے کا انتخاب کرے گا۔
خودکار طور پر خالی سرخیاں پُر کریں۔
ایک بار جب ایپلیکیشن پی ڈی ایف صفحہ سے متن نکال لیتی ہے، آپ اس متن کو کیپشن بنانے کے لیے استعمال کر سکتے ہیں۔
اہم رویہ یہ ہے کہ درخواست صرف خالی کیپشن فیلڈز میں بھرتی ہے۔ صارف کی طرف سے پہلے سے درج کیپشنز کو اوور رائٹ نہیں کیا جائے گا۔
ایپلی کیشن استعمال کرتی ہے: captionFromText() نکالے گئے متن کو صاف اور کم کرنے میں مددگار:
function captionFromText
var s = String(t || '')
.replace(/s+/g, ' ')
.trim();
if (letters(s) < 3) {
return '';
}
if (s.length <= 200) {
return s;
}
var cut = s.slice(0, 200);
var end = Math.max(
cut.lastIndexOf('. '),
cut.lastIndexOf('? '),
cut.lastIndexOf('! '),
cut.lastIndexOf('। ')
);
return end > 60
? cut.slice(0, end + 1)
: cut.replace(/s+S*$/, '') + '…';
}
یہ فنکشن کیا کرتا ہے:
- فراہم کردہ قدر کو سٹرنگ میں تبدیل کرتا ہے۔
- بار بار خالی جگہوں کو واحد خالی جگہوں سے بدلتا ہے اور شروع اور اختتامی خالی جگہوں کو ہٹاتا ہے۔
- یقینی بنائیں کہ آپ کے متن میں کیپشن کے طور پر مفید ہونے کے لیے کافی حروف ہیں۔
- اگر یہ 200 حروف یا اس سے کم ہے، تو پورا متن واپس آ جاتا ہے۔
- لمبے متن کے لیے، جملے کی حد میں کیپشن کو ختم کرنے کی کوشش کریں۔ اگر کوئی مناسب حد نہیں ہے تو، آخری نامکمل لفظ کو ہٹا دیں اور بیضوی کا اضافہ کریں۔
ایپلیکیشن پھر استعمال کرتی ہے: fillFromText() منتخب کردہ اسٹوری بورڈ صفحہ پر تیار کردہ کیپشن کا اطلاق کرتا ہے۔
function fillFromText() {
var bd = board(), list = bd.error ? [] : unique(bd.list), filled = 0, scans = 0;
list.forEach(function (n) {
if (captionFor(n)) { return; }
var c = captionFromText(state.texts[n - 1]);
if (c) {
state.captions[n] = c;
filled++;
var ta = ui.grid.querySelector('[data-cap="' + n + '"]');
if (ta) { ta.value = c; }
} else if (isScan(n)) {
scans++;
}
});
if (!state.opts.captions && filled) {
state.opts.captions = true;
savePrefs();
}
redrawSoon(0);
if (!list.length) {
toast(bd.error || 'No pages on the board.', 'error');
return;
}
toast(
filled
? plural(filled, 'caption', 'captions') +
' filled from the page text. Edit them in the cards below.' +
(scans
? ' ' + plural(scans, 'scanned page has', 'scanned pages have') +
' no text; use OCR for ' + (scans === 1 ? 'it' : 'them') + '.'
: '')
: scans
? 'The empty pages are scans with no text. Use Read with OCR.'
: 'Every panel already has a caption.'
);
}
کہ fillFromText() ایک فنکشن کال کے ساتھ شروع ہوتا ہے۔ board() فی الحال منتخب کردہ اسٹوری بورڈ صفحہ حاصل کرتا ہے۔ یہ استعمال کرتا ہے unique() ایک ہی صفحے پر ایک سے زیادہ بار کارروائی کرنے سے گریز کریں۔
ہر منتخب صفحہ کے لیے captionFor(n) چیک کریں کہ آیا کیپشن پہلے سے موجود ہے۔ اگر کوئی کیپشن موجود ہے تو فنکشن اس صفحہ کو چھوڑ دیتا ہے اور صارف کے موجودہ کیپشن کو اوور رائٹ نہیں کرتا ہے۔
اگر کیپشن خالی ہے تو فنکشن سرخی سے نکالے گئے متن کو تلاش کرتا ہے۔ state.texts اور اسے منتقل کریں captionFromText(). اگر مفید متن دستیاب ہو تو کیپشنز بنائے۔ state.captions صفحہ کارڈ پر متعلقہ ٹیکسٹ ایریا کو اپ ڈیٹ کرتا ہے۔
اگر کسی صفحہ میں نکالنے کے قابل متن نہیں ہے اور اسکین کے طور پر شناخت کی گئی ہے، تو یہ خصوصیت اسکین شدہ صفحات کے کاؤنٹر کو بڑھا دیتی ہے۔ صارفین ان صفحات کو الگ سے پروسیس کرنے کے لیے OCR کا استعمال کر سکتے ہیں۔
آخر میں، ایپلی کیشن ضرورت پڑنے پر کیپشنز کو چالو کرتی ہے، اپ ڈیٹ کردہ ترجیحات کو محفوظ کرتی ہے، اور پیش نظارہ ریفریشز کو شیڈول کرتی ہے۔ آپ کو ایک پیغام بھی نظر آئے گا جس میں دکھایا جائے گا کہ کتنے کیپشنز بھرے گئے ہیں یا OCR کی ضرورت ہے۔
یہ صارفین کو دستی طور پر لکھی گئی تفصیل کو محفوظ رکھتے ہوئے خود بخود ابتدائی سرخیاں پیدا کرنے کی اجازت دیتا ہے۔

اپ ڈیٹس کا پیش نظارہ کریں۔
جب بھی کیپشنز یا متعلقہ سیٹنگز تبدیل ہوں تو اسٹوری بورڈ کا پیش نظارہ ریفریش ہونا چاہیے۔
ایپلیکیشن ہر انفرادی تبدیلی کے لیے فوری طور پر پیش نظارہ کو دوبارہ بنانے سے بچنے کے لیے ایک چھوٹی سی شیڈولنگ خصوصیت کا استعمال کرتی ہے۔
function redrawSoon(ms) {
clearTimeout(drawTimer);
drawTimer = setTimeout(
drawPreview,
ms === undefined ? 120 : ms
);
}
کہ redrawSoon() فنکشن پہلے کسی بھی پہلے سے طے شدہ پیش نظارہ اپ ڈیٹس کو استعمال کرتے ہوئے منسوخ کرتا ہے: clearTimeout(). پھر اسے شیڈول کریں۔ drawPreview() استعمال کرتے ہوئے setTimeout().
پہلے سے طے شدہ طور پر، ایپلیکیشن پیش نظارہ کو تازہ کرنے سے پہلے 120 ملی سیکنڈ انتظار کرتی ہے۔ اگر اس وقت کے دوران کوئی اور تبدیلی واقع ہوتی ہے، تو پہلے سے طے شدہ دوبارہ قرعہ اندازی کو منسوخ کر دیا جاتا ہے اور ایک نیا دوبارہ ڈرا کرنا شیڈول کیا جاتا ہے۔
یہ غیر ضروری بار بار پیش کرنے سے روکنے میں مدد کرتا ہے کیونکہ صارفین کیپشن داخل کرتے ہیں یا ترتیبات کو ایڈجسٹ کرتے ہیں۔
تازہ ترین پیش نظارہ بنائیں
جب دوبارہ ڈرا شیڈول کیا جاتا ہے۔ drawPreview() فنکشن موجودہ اسٹوری بورڈ کنفیگریشن کا حساب لگاتا ہے اور دکھائے گئے پیش نظارہ کینوس کو اپ ڈیٹ کرتا ہے۔
درخواست کا اصل نفاذ یہ ہے:
async function drawPreview() {
if (!state.doc) { return; }
var my = ++drawToken, bd = board();
refreshTags(bd);
syncPanel();
if (bd.error) {
ui.boardMsg.textContent = bd.error;
ui.sheetPos.textContent="No sheets";
ui.sheetCount.textContent="";
root.querySelectorAll('[data-needs-board]').forEach(function (b) {
b.disabled = true;
});
return;
}
root.querySelectorAll('[data-needs-board]').forEach(function (b) {
b.disabled = state.busy;
});
var L = bd.L, o = state.opts;
state.sheet = clamp(state.sheet, 0, L.sheets - 1);
ui.boardMsg.textContent = L.tight
? 'Captions leave little room for the pages. Use fewer caption lines, fewer rows or a smaller text size.'
: '';
ui.sheetPos.textContent="Sheet " + (state.sheet + 1) + ' of ' + L.sheets;
ui.sheetCount.textContent =
plural(bd.list.length, 'panel', 'panels') + ' on ' +
plural(L.sheets, 'sheet', 'sheets') + ', ' +
PAPER_NAMES[o.paper] + ' ' + o.orient;
q('[data-act="sheet-prev"]').disabled = state.sheet <= 0;
q('[data-act="sheet-next"]').disabled = state.sheet >= L.sheets - 1;
ui.sheetWrap.style.aspectRatio = L.W + ' / ' + L.H;
var cssW = ui.sheetWrap.clientWidth || 600;
var dpr = Math.min(window.devicePixelRatio || 1, 2);
var k = cssW * dpr / L.W;
var off = document.createElement('canvas');
off.width = Math.round(L.W * k);
off.height = Math.round(L.H * k);
var done = await drawSheet(
off.getContext('2d'),
o,
bd.list,
L,
state.sheet,
k,
'full',
function (n, w, h) {
return my === drawToken
? cachedPic(n, w, h)
: Promise.resolve(null);
}
);
if (!done || my !== drawToken) { return; }
ui.sheet.width = off.width;
ui.sheet.height = off.height;
ui.sheet.getContext('2d').drawImage(off, 0, 0);
off.width = 1;
var start = state.sheet * L.per;
var on = bd.list.slice(start, start + L.per);
ui.sheet.setAttribute(
'aria-label',
'Sheet ' + (state.sheet + 1) + ' of ' + L.sheets + ': ' +
(on.length === 1 ? 'page ' + on[0] : 'pages ' + on.join(', '))
);
ui.sheet.setAttribute('data-drawn', String(state.sheet + 1));
}
یہ فیچر پہلے چیک کرتا ہے کہ آیا پی ڈی ایف دستاویز لوڈ ہوئی ہے۔ پھر کال کریں: board() منتخب صفحات کو بازیافت کرتا ہے اور اسٹوری بورڈ لے آؤٹ کا حساب لگاتا ہے۔
کہ drawToken قدر پرانے پیش نظارہ رینڈرنگ آپریشنز کو نئے کو تبدیل کرنے سے روکنے میں مدد کرتی ہے۔ یہ فنکشن بھی کال کرتا ہے: refreshTags() اور syncPanel() صفحہ کی معلومات اور ترتیبات کے پینل کو اپ ڈیٹ کریں۔
اگلا، غلطیوں کے لیے منتخب بورڈ کو چیک کریں۔ اگر انتخاب درست ہے، تو یہ شیٹ کی موجودہ پوزیشن کا حساب لگاتا ہے اور شیٹ کاؤنٹر، پینل کی گنتی، کاغذ کی معلومات، اور پچھلے اور اگلے بٹنوں کو اپ ڈیٹ کرتا ہے۔
فنکشن پھر دستیاب پیش نظارہ چوڑائی اور ڈیوائس پکسل تناسب کا استعمال کرتے ہوئے کینوس کے سائز کا حساب لگاتا ہے۔ رینڈرنگ ورک بوجھ کو محدود کرنے کے لیے، ڈیوائس کا پکسل تناسب 2 تک محدود ہے۔
کہ drawSheet() فنکشن منتخب اسٹوری بورڈ شیٹ کو عارضی کینوس پر کھینچتا ہے۔ وصول کریں cachedPic() کال بیک کے طور پر استعمال کیا جاتا ہے، جو پہلے پیش کیے گئے پی ڈی ایف صفحہ کے مناظر کو دوبارہ استعمال کرنے کی اجازت دیتا ہے۔
ڈرائنگ مکمل ہونے کے بعد، فنکشن چیک کرتا ہے کہ آیا آپریشن ابھی بھی جاری ہے۔ اگر ایسا ہے تو، مکمل شدہ عارضی کینوس کو مرئی پیش نظارہ کینوس میں کاپی کیا جائے گا۔
آخر میں، ہم اس کی چوڑائی کو 1 تک کم کرکے عارضی کینوس کو آزاد کرتے ہیں۔ ایپلیکیشن پیش نظارہ میں ایکسیسبیلٹی لیبل کو بھی اپ ڈیٹ کرتی ہے اور یہ ریکارڈ کرتی ہے کہ کون سی شیٹ کھینچی گئی تھی۔
یہ عمل صارفین کو اسٹوری بورڈ کی تبدیلیوں کو دیکھنے کی اجازت دیتا ہے جب بھی وہ کیپشنز یا سیٹنگز کو ایڈجسٹ کرتے ہیں تو نیا پی ڈی ایف ڈاؤن لوڈ کیے بغیر۔
اسٹوری بورڈ لے آؤٹ کا انتخاب کریں۔
یہ ٹول تین ترتیب طرزوں کو سپورٹ کرتا ہے: گرڈ، نوٹ کے ساتھ پینل، اور فلم اسٹریپ۔ ہر ترتیب مختلف قسم کے منصوبوں کو فٹ کرنے کے لیے ڈیزائن کیا گیا ہے۔
ایک گرڈ لے آؤٹ پی ڈی ایف صفحات کو قطاروں اور کالموں میں ترتیب دیتا ہے۔ پریزنٹیشن سلائیڈز، مزاحیہ صفحات اور دستاویزات کا جائزہ لینے کے لیے بہترین۔
نوٹ کے ساتھ ایک پینل ہر صفحے کے نیچے لکھنے کی اضافی جگہ فراہم کرتا ہے۔ لیکچر نوٹس، منصوبہ بندی، اور بصری مواد کا جائزہ لینے کے لیے مفید ہے۔
فلم کی پٹی ایک صفحے کو فریموں کی ایک سیریز میں ترتیب دیتی ہے۔ ویڈیوز، ریلیں اور مناظر کی منصوبہ بندی کے لیے مفید ہے۔
منتخب کردہ ترتیب کو ایپلیکیشن کی حالت میں محفوظ کیا جاتا ہے۔ اگر صارف ایک مختلف ترتیب کا انتخاب کرتا ہے، تو ایپلیکیشن مناسب ڈیفالٹ ترتیب فراہم کرنے کے لیے کالموں اور قطاروں کی تعداد کو اپ ڈیٹ کرتی ہے۔
ذیل میں اصل مواد کا ایک اقتباس ہے: onField() فنکشن لے آؤٹ تبدیلیوں کو سنبھالتا ہے۔
if (f === 'layout' && e.type === 'change') {
// sensible panel counts for each layout
if (o.layout === 'notes') {
o.cols = o.orient === 'landscape' ? 2 : 1;
o.rows = o.orient === 'landscape' ? 3 : 4;
}
if (o.layout === 'strip') {
o.cols = 4;
o.rows = o.orient === 'landscape' ? 2 : 4;
}
if (o.layout === 'grid') {
o.cols = o.orient === 'landscape' ? 3 : 2;
o.rows = o.orient === 'landscape' ? 2 : 3;
}
}
savePrefs();
if (f === 'cols' || f === 'rows' || f === 'layout') {
state.sheet = 0;
}
redrawSoon(f === 'gap' ? 60 : 0);
یہ کوڈ صارف کی طرف سے منتخب کردہ ترتیب کو چیک کرتا ہے اور ترتیب اور کاغذ کی سمت بندی کی بنیاد پر کالموں اور قطاروں کی ڈیفالٹ تعداد کو ایڈجسٹ کرتا ہے۔
مثال کے طور پر:
- نوٹ کے ساتھ پینل: افقی واقفیت 2 کالم اور 3 قطاروں کا استعمال کرتی ہے، اور عمودی واقفیت 1 کالم اور 4 قطاروں کا استعمال کرتی ہے۔
- فلم کی پٹی: یہ 4 کالم استعمال کرتا ہے: 2 قطاریں افقی طور پر اور 4 قطاریں عمودی طور پر۔
- گرڈ: افقی واقفیت 3 کالم اور 2 قطاریں استعمال کرتی ہے، اور عمودی واقفیت 2 کالم اور 3 قطاریں استعمال کرتی ہے۔
اس قدر کو اپ ڈیٹ کرنے کے بعد savePrefs() اپنی ترتیبات کو محفوظ کریں۔ جب لے آؤٹ تبدیل ہوتا ہے اور اسے کال کیا جاتا ہے، تو ایپلیکیشن موجودہ شیٹ کو پہلی شیٹ پر دوبارہ سیٹ کرتی ہے۔ redrawSoon() پیش منظر کو تازہ کرنے کے لیے
صارف بورڈ کی ترتیبات کا استعمال کرتے ہوئے قطاروں اور کالموں کی تعداد کو دستی طور پر ایڈجسٹ کر سکتے ہیں۔
قطاروں، کالموں اور کاغذ کے سائز کو کنٹرول کریں۔
صارف فی شیٹ 1 سے 6 کالموں اور قطاروں کے درمیان انتخاب کر سکتے ہیں۔ یہ آپ کو کنٹرول کرنے کی اجازت دیتا ہے کہ کتنے پی ڈی ایف صفحات ایک ساتھ دکھائے جائیں۔
مزید برآں، ایپلیکیشن A4، خط، A3، اور 16:9 سلائیڈ فارمیٹس سمیت متعدد کاغذی سائز کو سپورٹ کرتی ہے۔ ہر فارمیٹ کو یا تو پورٹریٹ یا زمین کی تزئین کی واقفیت میں دکھایا جا سکتا ہے۔
مثال کے طور پر، تین کالم بذریعہ دو قطار لے آؤٹ چھ پی ڈی ایف صفحات فی شیٹ دکھا سکتا ہے۔ چار کالم اور تین قطار والی ترتیب 12 صفحات کو ظاہر کر سکتی ہے۔
ایپلیکیشن منتخب کالموں کو منتخب قطاروں سے ضرب دے کر حساب لگاتی ہے کہ ہر شیٹ پر کتنے پینل فٹ ہوں گے۔ پھر اس بات کا تعین کریں کہ تمام منتخب صفحات کے لیے آپ کو کتنی شیٹس کی ضرورت ہے۔
حقیقی دنیا کی ایپلی کیشن میں درج ذیل فنکشن شیٹ کے سائز کو منتخب کاغذ کے سائز اور واقفیت کی بنیاد پر شمار کرتا ہے۔
function sheetSize(o) {
var p = PAPERS[o.paper] || PAPERS.a4;
var a = Math.min(p[0], p[1]);
var b = Math.max(p[0], p[1]);
return o.orient === 'portrait' ? [a, b] : [b, a];
}
کہ PAPERS آبجیکٹ میں ہر معاون کاغذی شکل کے سائز شامل ہیں۔ یہ فنکشن منتخب جہتوں کو بازیافت کرتا ہے اور منتخب سمت کے مطابق ترتیب دیتا ہے۔
پورٹریٹ واقفیت کے لیے، چھوٹا سائیڈ چوڑائی ہے اور لمبی سائیڈ اونچائی ہے۔ افقی واقفیت کے لیے، یہ جہتیں مخالف ہیں۔
ترتیب کا حساب کتاب پھر فی شیٹ پینلز کی تعداد کا تعین کرنے کے لیے منتخب قطاروں اور کالموں کا استعمال کرتا ہے۔
var per = o.cols * o.rows;
var sheets = Math.max(1, Math.ceil(list.length / per));
یہاں، per فی شیٹ پینلز کی تعداد کی نشاندہی کرتا ہے۔ کہ Math.ceil() فنکشن مطلوبہ شیٹس کی کل تعداد کو جمع کرتا ہے تاکہ باقی صفحات کو اضافی شیٹس پر رکھا جائے۔
لے آؤٹ انجن دستیاب جگہ کا بھی حساب لگاتا ہے اور ہر پینل کو پوزیشن دیتا ہے تاکہ صفحہ منتخب شیٹ کے سائز کے مطابق ہو۔
اگر آپ ایک شیٹ پر فٹ ہونے سے زیادہ صفحات کا انتخاب کرتے ہیں، تو باقی پینل اضافی شیٹس پر رکھے جائیں گے۔

پی ڈی ایف صفحات منتخب کریں اور آرڈر کریں۔
صارفین کو ہمیشہ اصل پی ڈی ایف کے تمام صفحات کی ضرورت نہیں ہوتی ہے۔
یہ ٹول تمام صفحات کو استعمال کرنے، صفحوں کی ایک رینج کو منتخب کرنے، یا حسب ضرورت صفحہ ترتیب داخل کرنے میں معاونت کرتا ہے۔
مثال کے طور پر، صارف ٹائپ کر سکتا ہے:
1-4, 9, 6
یہ صفحہ 1، 2، 3، 4، 9 اور 6 کو عین ترتیب میں استعمال کرتے ہوئے ایک اسٹوری بورڈ بنائے گا۔
ایپلی کیشن استعمال کرتی ہے: parseList() ایک فنکشن جو حسب ضرورت صفحہ کے انتخاب کو سنبھالتا ہے اور چیک کرتا ہے کہ آیا درخواست کردہ صفحہ نمبر درست ہے۔
درخواست کا اصل نفاذ یہ ہے:
function parseList(text) {
var t = String(text || '').trim();
if (!t) {
return { error: 'Type the pages, for example 1-4, 7, 5.' };
}
var out = [], parts = t.split(/[,;s]+/).filter(Boolean);
for (var i = 0; i < parts.length; i++) {
var part = parts[i],
m = /^(d+)(?:s*[-–]s*(d*))?$/.exec(part);
if (!m) {
return { error: '"' + part + '" isn't a page number or range.' };
}
var a = parseInt(m[1], 10),
b = m[2] === undefined
? a
: (m[2] === '' ? state.count : parseInt(m[2], 10));
if (a < 1) {
return { error: 'Pages start at 1, so "' + part + '" doesn't work.' };
}
if (b < a) {
return { error: '"' + part + '" is backwards. Did you mean ' + b + '-' + a + '?' };
}
if (a > state.count) {
return {
error: 'Page ' + a + ' is past the end; this PDF has ' +
plural(state.count, 'page', 'pages') + '.'
};
}
if (b > state.count) {
return {
error: 'Page ' + b + ' is past the end. Type ' + a +
'- to go to the last page.'
};
}
for (var n = a; n <= b; n++) {
out.push(n);
}
}
if (out.length > 500) {
return { error: 'That's ' + out.length + ' panels. Use 500 or fewer.' };
}
return { pages: out };
}
فنکشن پہلے ان پٹ کو تراشی ہوئی تار میں تبدیل کرتا ہے۔ پھر انتخاب کو تقسیم کرنے کے لیے کوما، نیم کالون یا خالی جگہوں کا استعمال کریں۔
ریگولر ایکسپریشن چیک کرتا ہے کہ آیا ہر آئٹم ایک صفحہ نمبر ہے یا صفحات کی ایک حد۔ مثال کے طور پر، 3 صفحہ 3 دکھاتا ہے، 2-5 صفحہ 2 سے 5 کی طرف اشارہ کرتا ہے۔
یہ فنکشن اوپن رینجز کو بھی سپورٹ کرتا ہے: 4-. اس معاملے میں درخواست استعمال کرتی ہے: state.count آخری صفحہ نمبر تک
نتائج میں صفحات شامل کرنے سے پہلے، اس بات کو یقینی بنائیں کہ صفحہ نمبر 1 سے شروع ہوں، کہ رینج صعودی ترتیب میں ہے، اور یہ کہ مطلوبہ صفحات پی ڈی ایف میں صفحات کی کل تعداد سے زیادہ نہ ہوں۔
مزید برآں، ایپلیکیشن حسب ضرورت انتخاب کو 500 پینلز تک محدود کرتی ہے۔ اگر ان پٹ درست ہے تو، فنکشن صفحہ نمبروں کی ایک صف واپس کرتا ہے جس ترتیب سے آپ نے انہیں درج کیا ہے۔
کہ panels() فنکشن پھر اسٹوری بورڈ بناتے وقت اس نتیجے کو استعمال کرتا ہے۔ اگر صارف اپنی مرضی کی فہرست میں داخل ہونے کے بجائے تمام صفحات کو منتخب کرتا ہے، تو تمام صفحات ان کی اصل ترتیب میں واپس آ جائیں گے۔
یہ خصوصیت اس وقت کارآمد ہوتی ہے جب پوری پی ڈی ایف کو شامل کیے بغیر منتخب مناظر یا اہم سلائیڈز سے اسٹوری بورڈ بناتے ہیں۔
پینل لیبل شامل کریں۔
پینل لیبل صارفین کو اسٹوری بورڈ کا جائزہ لینے یا اس پر بحث کرتے وقت انفرادی صفحات کی شناخت کرنے میں مدد کرتے ہیں۔
ایپلیکیشن مختلف قسم کے لیبل اسٹائل کو سپورٹ کرتی ہے، بشمول نمبرز، سین لیبلز، اصل پی ڈی ایف پیج نمبرز، اور کوئی لیبل نہیں۔
مثال کے طور پر، ایک اسٹوری بورڈ دکھا سکتا ہے:
- 1، 2، 3، 4
- سین 1، سین 2، سین 3
- صفحہ 5، صفحہ 6، صفحہ 7
صارفین پینل لیبل کی ترتیبات میں اپنا پسندیدہ لیبل طرز منتخب کر سکتے ہیں۔
ایپلی کیشن استعمال کرتی ہے: labelFor() ہر پینل کے لیے مناسب لیبل بنانے کے لیے ایک فنکشن:
function labelFor(o, idx, n) {
if (o.label === 'panel') {
return String(idx + 1);
}
if (o.label === 'page') {
return 'Page ' + n;
}
if (o.label === 'scene') {
return 'Scene ' + (idx + 1);
}
return '';
}
یہ فنکشن تین پیرامیٹرز کو قبول کرتا ہے۔
oاسٹوری بورڈ کی ترتیبات پر مشتمل ہے، بشمول منتخب کردہ لیبل اسٹائل۔idxمنتخب اسٹوری بورڈ ترتیب میں پینل کی پوزیشن کی نشاندہی کرتا ہے۔ یہ 0 سے شروع ہوتا ہے۔nاصل پی ڈی ایف صفحہ نمبر کی نشاندہی کرتا ہے۔
جب صارف پینل نمبر کا اختیار منتخب کرتا ہے، idx + 1 1، 2، 3 جیسے لیبل بنائیں۔
جب صارف صفحہ نمبر کا اختیار منتخب کرتا ہے، تو فنکشن استعمال کرتا ہے: n اصل پی ڈی ایف صفحہ نمبر دکھاتا ہے۔ یہ مفید ہے اگر آپ کے اسٹوری بورڈ میں منتخب صفحات حسب ضرورت ترتیب میں ہوں۔
سین لیبلز کے آپشن کے لیے، فنکشن لیبل تیار کرتا ہے جیسے سین 1، سین 2، اور سین 3۔ اگر صارف کوئی لیبل نہیں منتخب کرتا ہے، تو ایک خالی سٹرنگ واپس آ جاتی ہے۔
ڈرائنگ فنکشن اسٹوری بورڈ شیٹ کے ہر پینل کو پیش کرتے وقت ان نتائج کو استعمال کرتا ہے۔ یہ صارفین کو اصل پی ڈی ایف صفحہ کو تبدیل کیے بغیر انفرادی پینلز کی شناخت کرنے کی اجازت دیتا ہے۔
اسٹوری بورڈ شیٹ ڈرائنگ
لے آؤٹ کا حساب لگانے کے بعد، ایپلیکیشن HTML کینوس پر اسٹوری بورڈ شیٹ کھینچتی ہے۔
ڈرائنگ کا عمل ہر منتخب پی ڈی ایف صفحہ کو حسابی پینل کے علاقے میں رکھتا ہے۔ پھر اپنی ترتیبات کے مطابق پینل لیبل اور کیپشن شامل کریں۔
حقیقی دنیا کی ایپلی کیشنز غیر مطابقت پذیر طریقے استعمال کرتی ہیں۔ drawSheet() یہ اس عمل کا فنکشن ہے۔ مندرجہ ذیل اقتباس سے پتہ چلتا ہے کہ شیٹ کیسے تیار کی جائے اور شیٹ سے تعلق رکھنے والے صفحات کو کیسے منتخب کیا جائے۔
async function drawSheet(ctx, o, list, L, sheetIdx, k, mode, getPic) {
var C = COLORS[o.colors] || COLORS.paper;
var W = L.W * k;
var H = L.H * k;
var token = state.loadToken;
var drawn = [];
ctx.save();
ctx.fillStyle = C.bg;
ctx.fillRect(0, 0, W, H);
ctx.textBaseline="alphabetic";
var start = sheetIdx * L.per;
var items = list.slice(start, start + L.per);
یہ فنکشن کینوس کا سیاق و سباق، اسٹوری بورڈ سیٹنگز، منتخب صفحہ کی فہرست، کمپیوٹیڈ لے آؤٹ، شیٹ انڈیکس، اور رینڈرنگ اسکیل حاصل کرتا ہے۔
سب سے پہلے، شیٹ کا رنگ منتخب کریں اور پس منظر کو پینٹ کریں۔ کہ start متغیر موجودہ شیٹ کے پہلے پینل کا تعین کرتا ہے، items اس شیٹ کو تفویض کردہ پی ڈی ایف صفحات پر مشتمل ہے۔
مندرجہ ذیل اقتباس سے پتہ چلتا ہے کہ کس طرح ایپلی کیشن ہر پی ڈی ایف صفحہ کو پینل کے اندر فٹ کرتی ہے اور پیش کردہ تصویر کو بازیافت کرتی ہے۔
for (var i = 0; i < items.length; i++) {
var cell = L.cells[i], n = items[i], idx = start + i;
var area = cell.img;
var strip = o.layout === 'strip';
if (strip) {
ctx.fillStyle = C.bandMat;
ctx.fillRect(
area.x * k, area.y * k,
area.w * k, area.h * k
);
} else if (o.frame) {
ctx.fillStyle = C.mat;
ctx.fillRect(
area.x * k, area.y * k,
area.w * k, area.h * k
);
}
var inset = strip ? 0 :
o.frame ? Math.min(area.w, area.h) * 0.04 : 0;
var pr = fitPage(n, area, inset);
var px = {
x: Math.round(pr.x * k),
y: Math.round(pr.y * k),
w: Math.max(1, Math.round(pr.w * k)),
h: Math.max(1, Math.round(pr.h * k))
};
drawn.push({ n: n, rect: pr });
if (mode === 'overlay') {
ctx.clearRect(px.x, px.y, px.w, px.h);
} else {
ctx.fillStyle="#FFFFFF";
ctx.fillRect(px.x, px.y, px.w, px.h);
var pic = getPic ? await getPic(n, px.w, px.h) : null;
if (token !== state.loadToken) {
ctx.restore();
return null;
}
if (pic) {
ctx.drawImage(pic, px.x, px.y, px.w, px.h);
}
}
}
کہ fitPage() فنکشن اس کے تناسب کو تبدیل کیے بغیر اصل پی ڈی ایف صفحہ کو پینل کے اندر فٹ کرنے کے لیے درکار پوزیشن اور سائز کا حساب لگاتا ہے۔
ایپلیکیشن پھر استعمال کرتی ہے: getPic() پیش کردہ صفحہ کی تصویر بازیافت کرتا ہے۔ اگر تصویر دستیاب ہے، drawImage() اسے اسٹوری بورڈ کینوس پر رکھیں۔
یہ فیچر اوورلے موڈ کو بھی سپورٹ کرتا ہے، جو صفحہ کی تصویر کے علاقے کو شفاف رکھتا ہے۔ پی ڈی ایف کے اصل مواد کو برقرار رکھتے ہوئے پی ڈی ایف ایکسپورٹ کرتے وقت یہ مفید ہے۔
ڈرائنگ پینل لیبلز اور کیپشنز
صفحہ کے پیش نظارہ کو پوزیشن دینے کے بعد، ایپلیکیشن پینل لیبلز اور سرخیاں کھینچتی ہے۔
ذیل میں اصل مواد کا ایک اقتباس ہے: drawSheet() فنکشن یہ ظاہر کرتا ہے کہ کینوس پر پینل لیبلز اور کیپشن کیسے بنائے جاتے ہیں۔
var t = cell.text;
var fs = cell.fs * k;
var lh = cell.lh * k;
var y = t.y * k + fs;
var label = labelFor(o, idx, n);
ctx.textAlign = 'left';
if (label) {
ctx.font="700 " + fs + 'px ' + FONTS.mono;
ctx.fillStyle = C.ink;
ctx.fillText(label, t.x * k, y);
y += lh * 1.05;
}
var lines = [];
if (o.captions && captionFor(n)) {
ctx.font="400 " + fs + 'px ' + FONTS[o.font];
ctx.fillStyle = C.ink;
var maxL = cell.notes
? Math.max(1, Math.floor(
(t.y * k + t.h * k - y + lh - fs) / lh
))
: o.lines;
lines = wrap(
ctx,
captionFor(n),
t.w * k,
Math.min(maxL, cell.notes ? 40 : o.lines)
);
lines.forEach(function (ln, j) {
ctx.fillText(ln, t.x * k, y + j * lh);
});
}
کہ labelFor() فنکشن ایک منتخب پینل لیبل بناتا ہے۔ ایپلیکیشن پھر استعمال کرتی ہے: fillText() میں کینوس پر نقش کرنا چاہتا ہوں۔
اگر کیپشنز فعال ہیں اور کیپشنز موجود ہیں تو ایپلیکیشن استعمال کرتی ہے: captionFor() اسے تلاش کریں۔ کہ wrap() یہ خصوصیت سرخیوں کو ان لائنوں میں توڑ دیتی ہے جو دستیاب پینل کی جگہ میں فٹ ہوتی ہیں۔
نوٹ لے آؤٹ والے پینلز کے لیے، ایپلیکیشن کیپشن ایریا کے نیچے گرڈ لائنز بھی کھینچتی ہے۔ یہ صارفین کو لکھنے کی اضافی جگہ فراہم کرتا ہے۔
ڈرائنگ کا عمل ایک مکمل اسٹوری بورڈ شیٹ بنانے کے لیے اصل پی ڈی ایف صفحات کے پیش نظاروں کو لیبلز، کیپشنز، فریموں اور دیگر منتخب ترتیبات کے ساتھ جوڑتا ہے۔

ریئل ٹائم پیش نظارہ اپ ڈیٹس
سب سے مفید خصوصیات میں سے ایک لائیو پیش نظارہ ہے۔ صارفین ہر بار نیا پی ڈی ایف بنائے بغیر لے آؤٹ، کاغذ کا سائز، واقفیت، کیپشن، فونٹس، اسپیسنگ اور دیگر سیٹنگز کو تبدیل کر سکتے ہیں۔
ایپلی کیشن استعمال کرتی ہے: board() فنکشن جو پیش نظارہ ڈرائنگ کرنے سے پہلے موجودہ اسٹوری بورڈ کنفیگریشن کا حساب لگاتا ہے۔
یہاں اصل عمل درآمد ہے:
function board() {
var sel = panels();
if (sel.error) {
return { error: sel.error };
}
var L = layout(state.opts, sel.pages);
return {
list: sel.pages,
L: L
};
}
فنکشن کو پہلے کہا جاتا ہے۔ panels() منتخب پی ڈی ایف صفحات تلاش کریں۔ اگر انتخاب میں کوئی خامی ہے تو جاری رکھنے کے بجائے اس غلطی کو واپس کریں۔
اسے اگلا کہا جاتا ہے: layout() موجودہ اسٹوری بورڈ کی ترتیبات اور منتخب صفحات کا استعمال کرتا ہے۔ لے آؤٹ فنکشن اس بات کا حساب لگاتا ہے کہ اسٹوری بورڈ شیٹ پر صفحات کو کس طرح ترتیب دیا جانا چاہیے۔
آخر کار board() ایک آبجیکٹ لوٹاتا ہے جس میں منتخب صفحات کی فہرست اور ان کے حسابی ترتیب شامل ہیں۔ کہ drawPreview() فنکشن اس معلومات کو منتخب شیٹ کو عارضی کینوس پر رینڈر کرنے کے لیے استعمال کرتا ہے۔
ڈرائنگ مکمل ہونے کے بعد، نتیجہ ایک مرئی پیش نظارہ کینوس پر کاپی ہو جاتا ہے۔ ایپلیکیشن درج ذیل شیٹ کاؤنٹرز کو بھی اپ ڈیٹ کرتی ہے۔ Sheet 1 of 3آپ کے موجودہ مقام کے لحاظ سے پچھلے اور اگلے بٹنوں کو فعال یا غیر فعال کرتا ہے۔
یہ صارفین کو اسٹوری بورڈ شیٹس کے درمیان منتقل ہونے اور نتائج ڈاؤن لوڈ کرنے سے پہلے تبدیلیوں کا جائزہ لینے کی اجازت دیتا ہے۔
سرخی کی ظاہری شکل کو ایڈجسٹ کریں۔
کیپشن ہر صفحہ پر کیا ہو رہا ہے اس کی وضاحت کرنے میں مدد کرتے ہیں۔
ایپلی کیشن کیپشنز کو چالو کرنے، فونٹس کو منتخب کرنے، ٹیکسٹ سائز تبدیل کرنے اور کیپشن لائنوں کی تعداد کو کنٹرول کرنے کے اختیارات فراہم کرتی ہے۔
صارف یہ بھی منتخب کر سکتے ہیں کہ آیا پینل کے فریم اور شیٹ نمبر ڈسپلے کرنا ہے۔
یہ ترتیبات درج ذیل جگہ پر محفوظ کی گئی ہیں: state.opts. کہ syncPanel() فنکشن موجودہ ایپلیکیشن کی حالت سے ملنے کے لیے سیٹنگز کنٹرول کو اپ ڈیٹ کرتا ہے۔
یہاں اصل عمل درآمد ہے:
function syncPanel() {
var o = state.opts;
['layout', 'cols', 'rows', 'paper', 'orient', 'label',
'lines', 'tsize', 'font', 'colors'].forEach(function (f) {
q('[data-field="' + f + '"]').value = String(o[f]);
});
q('[data-field="captions"]').checked = o.captions;
q('[data-field="frame"]').checked = o.frame;
q('[data-field="numbers"]').checked = o.numbers;
q('[data-field="gap"]').value = String(o.gap);
q('[data-out="gap-val"]').textContent = o.gap + ' mm';
q('[data-field="pages"]').value = state.pages;
if (document.activeElement !== q('[data-field="title"]')) {
q('[data-field="title"]').value = state.title;
}
var strip = o.layout === 'strip';
q('[data-out="cols-label"]').textContent =
strip ? 'Frames per strip' : 'Columns';
q('[data-out="rows-label"]').textContent =
strip ? 'Strips per sheet' : 'Rows';
q('[data-field="lines"]').disabled =
!o.captions || o.layout === 'notes';
q('[data-field="frame"]').disabled = strip;
ui.listWrap.hidden = state.pages !== 'list';
}
یہ فنکشن موجودہ اختیارات کو اس سے پڑھتا ہے: state.opts اس کنٹرول کو اپ ڈیٹ کریں۔ مثال کے طور پر، منتخب فونٹ، متن کا سائز، سرخی کی لکیروں کی تعداد، اور کاغذ کی ترتیبات سیٹ کریں۔
یہ لے آؤٹ مخصوص کنٹرولز کو بھی ہینڈل کرتا ہے۔ فلم سٹرپ موڈ میں، کالم اور قطار کے لیبل فریم فی سٹرپ اور سٹرپس فی شیٹ میں بدل جاتے ہیں۔ سرخی کی لائن کنٹرول کو اس وقت غیر فعال کر دیا جاتا ہے جب کیپشنز بند ہو جاتے ہیں یا جب نوٹ لے آؤٹ والا پینل منتخب کیا جاتا ہے۔
پینل کے اندر کیپشن فٹ کریں۔
طویل سرخیاں دستیاب پینل کی جگہ میں فٹ ہونے چاہئیں۔ درخواست wrap() ایک مددگار جو دستیاب کینوس کی چوڑائی کی بنیاد پر متن کو لائنوں میں تقسیم کرتا ہے۔
اپنے اصل ڈرائنگ کوڈ میں اس مددگار کو استعمال کرنے کا طریقہ یہاں ہے:
if (o.captions && captionFor(n)) {
ctx.font="400 " + fs + 'px ' + FONTS[o.font];
ctx.fillStyle = C.ink;
var maxL = cell.notes
? Math.max(1, Math.floor(
(t.y * k + t.h * k - y + lh - fs) / lh
))
: o.lines;
lines = wrap(
ctx,
captionFor(n),
t.w * k,
Math.min(maxL, cell.notes ? 40 : o.lines)
);
lines.forEach(function (ln, j) {
ctx.fillText(ln, t.x * k, y + j * lh);
});
}
ایپلیکیشن اس کا استعمال کرتے ہوئے فونٹ کا انتخاب کرتی ہے: FONTS[o.font] پینل لے آؤٹ کی بنیاد پر دستیاب کیپشن لائنوں کی تعداد کا حساب لگاتا ہے۔
عام ترتیب کے لیے، منتخب کریں۔ o.lines ترتیبات لائنوں کی زیادہ سے زیادہ تعداد کو کنٹرول کرتی ہیں۔ نوٹ والے پینلز کے لیے، دستیاب جگہ ان لائنوں کی تعداد کا تعین کرتی ہے جو ظاہر کی جا سکتی ہیں۔
کہ wrap() فنکشن کیپشن کو ان لائنوں میں تقسیم کرتا ہے جو دستیاب چوڑائی کے مطابق ہوں۔ کہ fillText() طریقہ پھر کینوس پر ہر ایک لائن کو کھینچتا ہے۔
اگر آپ کی منتخب کردہ سرخی کی ترتیب کے لیے کافی جگہ نہیں ہے، تو پیش نظارہ ایک انتباہ دکھاتا ہے جو تجویز کرتا ہے کہ آپ سرخی کی لائنوں، قطاروں، یا متن کے سائز کی تعداد کو کم کریں۔
ایپلیکیشن پینل فریموں اور شیٹ نمبروں کو بھی سپورٹ کرتی ہے۔ یہ اختیارات ایپلیکیشن کی حالت میں محفوظ ہوتے ہیں اور اسٹوری بورڈ ڈرائنگ کرتے وقت لاگو ہوتے ہیں۔
یہ صارفین کو اصل پی ڈی ایف کو تبدیل کیے بغیر اسٹوری بورڈ کیپشن کی ظاہری شکل اور پڑھنے کی اہلیت کو کنٹرول کرنے کی اجازت دیتا ہے۔
اسٹوری بورڈ شیٹس کے درمیان نیویگیٹنگ
بڑی PDFs کے لیے متعدد اسٹوری بورڈ شیٹس کی ضرورت پڑ سکتی ہے۔
ایپلیکیشن پچھلے اور اگلے کنٹرول فراہم کرتی ہے تاکہ صارفین کو ہر شیٹ کا انفرادی طور پر جائزہ لینے کی اجازت دی جا سکے۔ یہ موجودہ شیٹ نمبر اور شیٹس کی کل تعداد بھی دکھاتا ہے۔
منتخب کردہ شیٹس کو درج ذیل جگہ پر محفوظ کیا گیا ہے۔ state.sheet. ایپلیکیشن اس قدر کا استعمال اس بات کا تعین کرنے کے لیے کرتی ہے کہ کون سی اسٹوری بورڈ شیٹ کو ڈسپلے کرنا ہے۔
پچھلا اور اگلا بٹن ہینڈلنگ
ایپلیکیشن ڈیفالٹ کلک ایونٹ سننے والے کے اندر شیٹ نیویگیشن کو ہینڈل کرتی ہے۔ یہاں اصل عمل درآمد ہے:
case 'sheet-prev':
if (state.sheet > 0) {
state.sheet--;
drawPreview();
}
break;
case 'sheet-next':
state.sheet++;
drawPreview();
break;
جب صارف پچھلا پر کلک کرتا ہے، تو ایپلیکیشن چیک کرتی ہے کہ آیا موجودہ شیٹ نمبر 0 سے زیادہ ہے۔ اگر ایسا ہے تو، state.sheet 1 کی کمی drawPreview() ظاہر شدہ شیٹ کو تازہ کرتا ہے۔
جب صارف نیکسٹ پر کلک کرتا ہے تو شیٹ نمبر بڑھ جاتا ہے اور پیش نظارہ تازہ ہوجاتا ہے۔
مزید برآں، ایپلی کیشن صارفین کو دستیاب نشستوں سے آگے بڑھنے سے روکتی ہے۔ اندر drawPreview()شیٹ کی موجودہ پوزیشن چیک کریں اور اگر ضروری ہو تو نیویگیشن بٹن کو غیر فعال کریں۔
state.sheet = clamp(state.sheet, 0, L.sheets - 1);
ui.sheetPos.textContent="Sheet " + (state.sheet + 1) + ' of ' + L.sheets;
q('[data-act="sheet-prev"]').disabled = state.sheet <= 0;
q('[data-act="sheet-next"]').disabled =
state.sheet >= L.sheets - 1;
کہ clamp() فنکشن منتخب شیٹس کو ایک درست رینج میں رکھتا ہے۔ سیٹ کاؤنٹر 1 سے شروع ہوتا ہے اور موجودہ پوزیشن اور سیٹوں کی کل تعداد دکھاتا ہے۔
پچھلا بٹن پہلی شیٹ پر غیر فعال ہے اور اگلا بٹن آخری شیٹ پر غیر فعال ہے۔ اس سے اسٹوری بورڈ کی تمام شیٹس کو ایک ساتھ ڈسپلے کیے بغیر بڑی دستاویزات کا جائزہ لینا آسان ہوجاتا ہے۔
OCR کے ساتھ اسکین شدہ صفحات پڑھیں
کچھ پی ڈی ایف دستاویزات میں قابل انتخاب متن ہوتا ہے، جبکہ دیگر پرنٹ شدہ صفحات کی اسکین شدہ تصاویر پر مشتمل ہوتے ہیں۔
PDF.js ان صفحات سے متن نکال سکتا ہے جن میں اصل ٹیکسٹ ڈیٹا ہوتا ہے۔ تاہم، الفاظ کو براہ راست اسکین کیے گئے صفحات سے نہیں نکالا جا سکتا جس میں صرف تصاویر ہوں۔
ان صفحات پر کارروائی کرنے کے لیے، ایپلیکیشن اختیاری OCR فعالیت فراہم کرنے کے لیے Tesseract.js کا استعمال کرتی ہے۔
جب صارف OCR کے ساتھ اسکین شدہ صفحات کو پڑھنے کا انتخاب کرتا ہے، تو ایپلیکیشن ان اسکین شدہ صفحات کی نشاندہی کرتی ہے جن کے پاس ابھی تک کیپشن نہیں ہیں اور OCR انجن کا استعمال کرتے ہوئے ان پر کارروائی کرتی ہے۔
ضرورت پڑنے پر Tesseract.js لوڈ کریں۔
ایپلیکیشن Tesseract.js کو صرف اس وقت لوڈ کرتی ہے جب صارف OCR کی درخواست کرتا ہے۔ پہلے یہ چیک کرتا ہے کہ آیا لائبریری پہلے سے دستیاب ہے اور اگر اسکرپٹ اب بھی لوڈ ہو رہا ہے تو یہ موجودہ لوڈ وعدے کو دوبارہ استعمال کرتا ہے۔
یہاں اصل مواد ہے: loadTesseract() اوتار:
var tessPromise = null;
function loadTesseract() {
if (window.Tesseract) {
return Promise.resolve(window.Tesseract);
}
if (tessPromise) {
return tessPromise;
}
tessPromise = new Promise(function (resolve, reject) {
var s = document.createElement('script');
s.src = TESS + 'tesseract.min.js';
s.async = true;
s.onload = function () {
if (window.Tesseract) {
resolve(window.Tesseract);
} else {
tessPromise = null;
reject(new Error('engine'));
}
};
s.onerror = function () {
tessPromise = null;
reject(new Error('engine'));
};
document.head.appendChild(s);
setTimeout(function () {
reject(new Error('engine'));
}, 45000);
});
return tessPromise;
}
فنکشن چیک window.Tesseract چیک کریں کہ آیا OCR لائبریری پہلے سے دستیاب ہے۔ اگر ایسا ہے تو، فنکشن اسے فوری طور پر واپس کرتا ہے۔
اگر لائبریری اب بھی لوڈ ہو رہی ہے، tessPromise ایک اور اسکرپٹ کی درخواست پیدا کرنے کے بجائے واپس آ گیا۔
بصورت دیگر، ایپلیکیشن اسکرپٹ کا عنصر بناتی ہے، اپنا ماخذ Tesseract.js لائبریری میں سیٹ کرتی ہے، اور اسے دستاویز میں شامل کرتی ہے۔ کہ onload اور onerror ہینڈلر پتہ لگاتا ہے کہ لوڈنگ کامیاب ہوئی یا ناکام۔
ایک OCR کارکن بنائیں
لائبریری لوڈ ہونے کے بعد، ایپلیکیشن انگریزی متن کی شناخت کے لیے ترتیب شدہ ٹیسریکٹ ورکر بناتی ہے۔
مندرجہ ذیل اصل متن سے ایک اقتباس ہے: runOcr() فنکشن:
var T = await loadTesseract();
checkCancel();
var w = await T.createWorker('eng', 1, {
workerPath: TESS + 'worker.min.js',
corePath: TESS_CORE,
logger: function (m) {
if (!m || token !== state.loadToken || !state.busy) {
return;
}
if (/loading language/i.test(m.status)) {
setProgress(
m.progress || 0,
'Getting the English language data (first time only)…'
);
} else if (/recogniz/i.test(m.status)) {
setProgress(
(done + (m.progress || 0)) / list.length,
'Reading page ' + list[done] +
' (' + (done + 1) + ' of ' + list.length + ')…'
);
}
}
});
state.worker = w;
checkCancel();
await w.setParameters({ debug_file: '/dev/null' });
کہ createWorker() طریقہ انگریزی ڈیٹا کے ساتھ OCR انجن کو شروع کرتا ہے۔ کارکن اور بنیادی راستہ Tesseract.js کو بتاتا ہے کہ سپورٹ فائلیں کہاں لوڈ کرنی ہیں۔
لاگر زبان کی لوڈنگ اور متن کی شناخت کی پیشرفت کی اطلاع دیتا ہے۔ ایپلیکیشن اس معلومات کو OCR کے چلنے کے دوران ترقی کے اشارے کو اپ ڈیٹ کرنے کے لیے استعمال کرتی ہے۔
اسکین شدہ صفحات سے متن کو پہچانیں۔
درخواست ہر اہل اسکین شدہ صفحہ پر انفرادی طور پر کارروائی کرتی ہے۔ Tesseract.js پر بھیجنے سے پہلے صفحہ کو ایک اعلی ریزولیوشن پر رینڈر کریں۔
صفحہ کی اصل پروسیسنگ مندرجہ ذیل ہے: runOcr():
for (; done < list.length; done++) {
checkCancel();
var n = list[done],
page = await state.doc.getPage(n),
b = page.getViewport({ scale: 1 });
var c = await renderPage(
n,
Math.min(b.width * 300 / 72, 2600),
Math.min(b.height * 300 / 72, 2600)
);
checkCancel();
var png = await pngBytes(c);
c.width = 1;
var res = await w.recognize(png);
checkCancel();
if (token !== state.loadToken) {
return;
}
var cap = captionFromText(res.data && res.data.text);
if (cap && !captionFor(n)) {
state.captions[n] = cap;
var ta = ui.grid.querySelector('[data-cap="' + n + '"]');
if (ta) {
ta.value = cap;
}
}
}
یہ فیچر ہر اسکین شدہ پی ڈی ایف پیج کو تلاش کرتا ہے اور اس کے اصل سائز کا حساب لگاتا ہے۔ اس کے بعد صفحہ کو تقریباً 300 ڈی پی آئی پر رینڈر کیا جاتا ہے، جس کا زیادہ سے زیادہ سائز 2,600 پکسلز ہوتا ہے۔
کہ pngBytes() مددگار پیش کردہ کینوس کو PNG تصویری ڈیٹا میں تبدیل کرتا ہے۔ Tesseract.js یہ ڈیٹا بذریعہ وصول کرتا ہے: w.recognize(png) تسلیم شدہ متن لوٹاتا ہے۔
ایپلیکیشن تسلیم شدہ متن کو اس پر منتقل کرتی ہے: captionFromText() صاف کریں اور مختصر کریں۔ اگر نتائج کارآمد ہیں اور صفحہ پر اب بھی کوئی کیپشن نہیں ہے، تو ایپلیکیشن درج ذیل جگہ پر کیپشنز کو اسٹور کرتی ہے۔ state.captions متعلقہ کیپشن فیلڈ کو اپ ڈیٹ کریں۔
ایپلیکیشن نتائج کو اپ ڈیٹ کرنے سے پہلے منسوخی کی جانچ بھی کرتی ہے اور اس بات کو یقینی بناتی ہے کہ پی ڈی ایف لوڈ آپریشن ابھی تک اپ ٹو ڈیٹ ہے۔
پروسیسنگ کے بعد، ایپلیکیشن ایک پیغام دکھاتی ہے جس میں صارف سے تیار کردہ کیپشنز کا جائزہ لینے کو کہا جاتا ہے۔ OCR اس بات کی ضمانت نہیں دیتا کہ ہر لفظ کو صحیح طریقے سے پہچانا جائے گا۔ تصویر کا معیار، ہینڈ رائٹنگ، غیر معمولی فونٹس، اور صفحہ کی سمت بندی نتائج کو متاثر کر سکتی ہے۔
صارفین کو اسٹوری بورڈ ڈاؤن لوڈ کرنے سے پہلے تیار کردہ سرخیوں کا جائزہ لینا چاہیے۔

فائنل اسٹوری بورڈ پی ڈی ایف بنائیں
ایک بار جب صارف ترتیب اور سرخیوں سے مطمئن ہو جاتا ہے، تو ایپلیکیشن حتمی پی ڈی ایف تیار کر سکتی ہے۔
یہ عمل PDF-lib کا استعمال کرتا ہے تاکہ ایک نیا PDF دستاویز بنایا جا سکے۔ ایپلیکیشن ہر اسٹوری بورڈ شیٹ کے لیے ایک آؤٹ پٹ صفحہ تیار کرتی ہے۔ پھر اصل پی ڈی ایف صفحہ کو حسابی پینل پوزیشن کے اندر رکھیں اور اسٹوری بورڈ سے عنوان، لیبل اور کیپشن شامل کریں۔
پی ڈی ایف دستاویز بنائیں
ایک حقیقی درخواست میں آپ استعمال کریں گے: exportPdf() یہ فنکشن اسٹوری بورڈ بناتا ہے۔ سب سے پہلے، ایک نئی PDF دستاویز بنائیں اور یقینی بنائیں کہ آپ اصل PDF صفحات کو ویکٹر مواد کے طور پر شامل کر سکتے ہیں۔
یہاں اصل نفاذ کا پہلا حصہ ہے:
async function exportPdf(snap, token) {
await engine();
var PL = window.PDFLib,
L = snap.L,
o = snap.o,
list = snap.list;
var out = await PL.PDFDocument.create(),
src = null,
embedded = {};
if (state.vector) {
try {
src = await PL.PDFDocument.load(
state.bytes.slice(0),
{ updateMetadata: false }
);
} catch (e) {
src = null;
}
}
var k = exportScale(L, 300, 14e6);
for (var s = 0; s < L.sheets; s++) {
checkCancel();
if (token !== state.loadToken) {
return;
}
setProgress(
s / L.sheets,
'Making sheet ' + (s + 1) + ' of ' + L.sheets + '…'
);
var page = out.addPage([L.W, L.H]);
var c = document.createElement('canvas');
c.width = Math.round(L.W * k);
c.height = Math.round(L.H * k);
var drawn = await drawSheet(
c.getContext('2d'),
o,
list,
L,
s,
k,
'overlay',
null
);
if (!drawn) {
return;
}
یہ فنکشن پہلے استعمال کرتے ہوئے مطلوبہ پی ڈی ایف لائبریری کا انتظار کرتا ہے: engine(). پھر استعمال کرتے ہوئے ایک نیا پی ڈی ایف دستاویز بنائیں: PDFDocument.create().
کہ snap پیرامیٹرز میں منتخب ترتیب، اختیارات اور صفحہ کی فہرست کا سنیپ شاٹ شامل ہوتا ہے۔ ایپلیکیشن ان اقدار کو استعمال کرتی ہے، لہذا برآمد آپ کی منتخب کردہ ترتیبات کی پیروی کرتی ہے۔
کہ state.vector چیک اس بات کا تعین کرتا ہے کہ آیا اصل PDF کو ویکٹر ایمبیڈنگ کے لیے PDF-lib کے ذریعے لوڈ کیا جا سکتا ہے۔ ایپلیکیشن زیادہ سے زیادہ پکسل کی حد کی بنیاد پر 300 DPI کو ہدف بنانے کے لیے رینڈرنگ پیمانے کا بھی حساب لگاتی ہے۔
لوپ ہر اسٹوری بورڈ شیٹ کے لیے ایک آؤٹ پٹ پی ڈی ایف صفحہ تیار کرتا ہے۔ اسے بھی کہا جاتا ہے۔ drawSheet() کو overlay عنوانات، پینل لیبلز، اور سرخیوں کو اصل پی ڈی ایف صفحات پر رکھنے کے لیے وضع کا استعمال کریں۔
اصل پی ڈی ایف صفحات کو محفوظ کریں۔
اگر ویکٹر ایمبیڈنگ ممکن ہے تو ایپلیکیشن اصل پی ڈی ایف پیج کو سادہ تصویر میں تبدیل کیے بغیر ایمبیڈ کر دے گی۔
مندرجہ ذیل اقتباس دکھاتا ہے کہ ہر منتخب پینل پر کیسے عمل کیا جائے۔
for (var i = 0; i < drawn.length; i++) {
checkCancel();
var d = drawn[i],
r = d.rect,
yb = L.H - r.y - r.h;
page.drawRectangle({
x: r.x,
y: yb,
width: r.w,
height: r.h,
color: PL.rgb(1, 1, 1)
});
if (src) {
var sp = src.getPage(d.n - 1);
if (!embedded[d.n]) {
var cb = sp.getCropBox();
embedded[d.n] = await out.embedPage(sp, {
left: cb.x,
bottom: cb.y,
right: cb.x + cb.width,
top: cb.y + cb.height
});
}
var em = embedded[d.n],
rot = ((sp.getRotation().angle % 360) + 360) % 360;
var turned = rot === 90 || rot === 270,
sx = r.w / (turned ? em.height : em.width);
var ew = em.width * sx,
eh = em.height * sx,
at = { x: r.x, y: yb };
if (rot === 90) {
at = { x: r.x, y: yb + ew };
} else if (rot === 180) {
at = { x: r.x + ew, y: yb + eh };
} else if (rot === 270) {
at = { x: r.x + eh, y: yb };
}
page.drawPage(em, {
x: at.x,
y: at.y,
width: ew,
height: eh,
rotate: PL.degrees(-rot)
});
}
ایپلیکیشن اصل پی ڈی ایف صفحہ کو بازیافت کرنے کے لیے صفحہ نمبر کا استعمال کرتی ہے۔ پھر استعمال کریں: embedPage() ان صفحات کو ایک نئی پی ڈی ایف دستاویز میں شامل کریں۔
کہ embedded آبجیکٹ ان صفحات کو کیش کرتا ہے جو اس میں موجود ہیں، اس لیے اسے بار بار وہی اصل صفحہ شامل کرنے کی ضرورت نہیں ہے۔
کوڈ اصل صفحہ کی گردش کو بھی چیک کرتا ہے اور صفحہ کھینچنے سے پہلے اس کی پوزیشن اور سائز کو ایڈجسٹ کرتا ہے۔ اس سے آپ کو اسٹوری بورڈ پینل میں صفحات لگاتے وقت مناسب سمت بندی برقرار رکھنے میں مدد ملے گی۔
محفوظ پی ڈی ایف پروسیسنگ
اگر اصل پی ڈی ایف کو ویکٹر مواد کے طور پر سرایت نہیں کیا جا سکتا، تو ایپلیکیشن راسٹر فال بیک کا استعمال کرتی ہے۔
اصل متبادل کوڈ یہ ہے:
else {
var pic = await renderPage(
d.n,
r.w * k,
r.h * k
);
var jpg = await new Promise(function (res) {
pic.toBlob(function (b) {
b.arrayBuffer().then(function (a) {
res(new Uint8Array(a));
});
}, 'image/jpeg', 0.92);
});
pic.width = 1;
page.drawImage(
await out.embedJpg(jpg),
{
x: r.x,
y: yb,
width: r.w,
height: r.h
}
);
}
اس صورت میں، ایپلیکیشن اصل پی ڈی ایف پیج کو کینوس میں رینڈر کرتی ہے اور اسے JPEG امیج ڈیٹا میں تبدیل کرتی ہے۔ PDF-lib پھر تصویر کو اس اسٹوری بورڈ پینل کے اندر ایمبیڈ کرتا ہے۔
یہ فال بیک اس وقت استعمال ہوتا ہے جب ویکٹر کا اندراج ممکن نہ ہو، بشمول محفوظ شدہ PDFs جہاں عام ویکٹر ورک فلو کی پیروی نہیں کی جا سکتی ہے۔
کیپشن شامل کریں اور پی ڈی ایف کو محفوظ کریں۔
صفحہ کی اصل تصویر یا ویکٹر مواد رکھنے کے بعد، ایپلیکیشن اسٹوری بورڈ سے عنوانات، لیبلز، کیپشنز اور دیگر ڈرائنگ عناصر کو اوورلیز کے طور پر شامل کرتی ہے۔
مندرجہ ذیل اقتباس دکھاتا ہے کہ کس طرح اوورلے کو شامل کیا جاتا ہے اور حتمی پی ڈی ایف کو محفوظ کیا جاتا ہے۔
var over = await out.embedPng(await pngBytes(c));
c.width = 1;
page.drawImage(over, {
x: 0,
y: 0,
width: L.W,
height: L.H
});
await nextFrame();
تمام شیٹس پر کارروائی کے بعد، درخواست منسوخی کی جانچ کرتی ہے اور حتمی پی ڈی ایف تیار کرتی ہے۔
checkCancel();
setProgress(1, 'Saving the PDF…');
out.setTitle(state.title || state.base + ' storyboard');
out.setCreator('AllInOneTools PDF Storyboard');
out.setProducer('AllInOneTools (pdf-lib)');
var bytes = await out.save();
if (token !== state.loadToken) {
return;
}
save(
new Blob([bytes], { type: 'application/pdf' }),
state.base + '-storyboard.pdf'
);
toast(
'Saved ' + plural(L.sheets, 'sheet', 'sheets') +
' as ' + state.base + '-storyboard.pdf.'
);
کہ embedPng() یہ طریقہ پی ڈی ایف پیج پر اسٹوری بورڈ اوورلے شامل کرتا ہے۔ اس اوورلے میں عنوانات، پینل لیبلز، کیپشنز اور دیگر بصری عناصر شامل ہیں۔
اس کے بعد ایپلیکیشن پی ڈی ایف میٹا ڈیٹا سیٹ کرتی ہے، دستاویز کو بائٹس کے طور پر محفوظ کرتی ہے، اور ڈاؤن لوڈ کے قابل پی ڈی ایف فائل بناتی ہے۔
پروگریس اپ ڈیٹس اور کینسلیشن چیکس کو ایکسپورٹ کے پورے عمل میں استعمال کیا جاتا ہے، جو کہ خاص طور پر ایک سے زیادہ شیٹس کے ساتھ اسٹوری بورڈز بناتے وقت مفید ہے۔
حتمی PDF اصل PDF صفحات کو اسٹوری بورڈ لے آؤٹ اور سرخیوں کے ساتھ جوڑتی ہے جسے آپ ڈاؤن لوڈ، اشتراک یا پرنٹ کرسکتے ہیں۔
PNG اسٹوری بورڈ شیٹ ڈاؤن لوڈ کریں۔
جن صارفین کو پی ڈی ایف کی ضرورت نہیں ہے وہ پی این جی شیٹس کا انتخاب کر سکتے ہیں۔
ایپلیکیشن ہر پوری اسٹوری بورڈ شیٹ کو 200 DPI پر PNG امیج کے طور پر پیش کرتی ہے۔ اگر آپ کے اسٹوری بورڈ میں صرف ایک شیٹ ہے تو براؤزر ایک ہی PNG فائل ڈاؤن لوڈ کرتا ہے۔ اگر متعدد شیٹس شامل ہیں، تو ایپلیکیشن انہیں زپ آرکائیو میں پیک کرتی ہے۔
اسٹوری بورڈ کو PNG کے بطور ایکسپورٹ کریں۔
ایپلیکیشن PNG برآمد کو اندرونی طور پر ہینڈل کرتی ہے۔ exportJob() فنکشن پہلے رینڈرنگ اسکیل کا حساب لگائیں اور پھر ہر اسٹوری بورڈ شیٹ پر کارروائی کریں۔
مندرجہ ذیل اقتباس اصل PNG برآمد کے نفاذ کو ظاہر کرتا ہے۔
var k = exportScale(L, 200, 16e6),
files = [];
for (var s = 0; s < L.sheets; s++) {
checkCancel();
setProgress(
s / L.sheets,
'Drawing sheet ' + (s + 1) + ' of ' + L.sheets + '…'
);
var c = document.createElement('canvas');
c.width = Math.round(L.W * k);
c.height = Math.round(L.H * k);
var ok = await drawSheet(
c.getContext('2d'),
o,
list,
L,
s,
k,
'full',
function (n, w, h) {
checkCancel();
return renderPage(n, w, h);
}
);
if (!ok) { return; }
files.push({
name: state.base + '-storyboard-sheet-' +
pad2(s + 1) + '.png',
data: await pngBytes(c)
});
c.width = 1;
}
if (files.length === 1) {
save(
new Blob([files[0].data], { type: 'image/png' }),
state.base + '-storyboard.png'
);
} else {
save(makeZip(files), state.base + '-storyboard-sheets.zip');
}
toast(
files.length === 1
? 'Saved the storyboard as a PNG.'
: 'Saved ' + files.length + ' sheets as PNG files in a ZIP.'
);
درخواست استعمال کرتا ہے exportScale() کینوس کو 16 ملین پکسلز کی زیادہ سے زیادہ پکسل کی حد میں رکھتے ہوئے 200 DPI کے لیے موزوں رینڈرنگ اسکیل کا حساب لگائیں۔
ہر شیٹ کے لیے کینوس بناتا اور کال کرتا ہے۔ drawSheet() کو full طریقہ یہ اسٹوری بورڈ کے عنوان، لیبلز، کیپشنز، اور آپ کی منتخب کردہ دیگر ترتیبات کے ساتھ پی ڈی ایف صفحہ کا پیش نظارہ بنائے گا۔
کہ pngBytes() مددگار مکمل کینوس کو PNG ڈیٹا میں تبدیل کرتا ہے۔ ہر تصویر ہے۔ files فائل کے ناموں والی ایک صف جس میں شیٹ نمبر ہیں۔
تمام شیٹس پر کارروائی کرنے کے بعد، ایپلیکیشن چیک کرتی ہے کہ کتنی PNG فائلیں بنی ہیں۔ سنگل شیٹس کو براہ راست PNG کے طور پر ڈاؤن لوڈ کیا جاتا ہے۔ ایک سے زیادہ شیٹس کو زپ آرکائیو میں استعمال کرتے ہوئے پیک کیا جاتا ہے: makeZip().
یہ فارمیٹ پریزنٹیشنز، پیغامات اور دیگر ایپلیکیشنز میں اسٹوری بورڈ کے پیش نظاروں کو شیئر کرنے کے لیے مفید ہے۔
انفرادی صفحہ کی تصاویر ڈاؤن لوڈ کریں۔
تیسرا ایکسپورٹ آپشن پیج فوٹوز (ZIP) ہے۔
PNG شیٹ آپشن کے برعکس، اس ایکسپورٹ میں اسٹوری بورڈ کے لیے منتخب کردہ PDF صفحات کی انفرادی تصاویر شامل ہیں۔
ایپلیکیشن ہر منتخب صفحہ کو الگ سے رینڈر کرتی ہے اور نتیجے میں آنے والی PNG فائلوں کو زپ آرکائیو میں محفوظ کرتی ہے۔
انفرادی پی ڈی ایف صفحات برآمد کریں۔
اصل ایپلیکیشن اس اختیار کو اندرونی طور پر ہینڈل کرتی ہے۔ exportJob() فنکشن یہ پہلے منتخب صفحات کی ایک منفرد فہرست بناتا ہے اور پھر ہر صفحہ کو انفرادی طور پر پیش کرتا ہے۔
یہاں اصل عمل درآمد ہے:
var pages = unique(list),
out = [];
for (var i = 0; i < pages.length; i++) {
checkCancel();
setProgress(
i / pages.length,
'Saving page ' + pages[i] +
' (' + (i + 1) + ' of ' + pages.length + ')…'
);
var pg = await state.doc.getPage(pages[i]),
vb = pg.getViewport({ scale: 1 }),
sc = Math.min(
2,
Math.sqrt(12e6 / (vb.width * vb.height))
);
var pc = await renderPage(
pages[i],
vb.width * sc,
vb.height * sc
);
out.push({
name: 'panel-' +
pad2(list.indexOf(pages[i]) + 1) +
'-page-' + pad2(pages[i]) + '.png',
data: await pngBytes(pc)
});
pc.width = 1;
}
save(makeZip(out), state.base + '-panels.zip');
toast(
'Saved ' +
plural(out.length, 'page picture', 'page pictures') +
' in a ZIP.'
);
فنکشن کو پہلے کہا جاتا ہے۔ unique() منتخب فہرست سے ڈپلیکیٹ صفحہ نمبروں کو ہٹانے کے لیے
اس کے بعد ہم ہر صفحے پر انفرادی طور پر کارروائی کرتے ہیں۔ کہ getPage() طریقہ اصل پی ڈی ایف صفحہ کو بازیافت کرتا ہے اور getViewport() آپ کو وہ جہت مل جاتی ہے۔
اسکیل کیلکولیشن رینڈرنگ فیکٹر کو 2 تک محدود کرتا ہے جبکہ رینڈر شدہ صفحہ کو تقریباً 12 ملین پکسلز کے اندر رکھتا ہے۔ یہ بڑے صفحات پر کارروائی کرتے وقت میموری کے استعمال کو کنٹرول کرنے میں مدد کرتا ہے۔
کہ renderPage() فنکشن صفحہ کی تصویر بناتا ہے، pngBytes() کینوس کو PNG ڈیٹا میں تبدیل کریں۔
ہر تصویر ہے۔ out فائل کے ناموں کے ساتھ ایک صف جس میں پینل پوزیشنز اور اصل PDF صفحہ نمبر دونوں شامل ہیں۔ اس سے تصویروں کی شناخت اور اسٹوری بورڈ کی ترتیب کو برقرار رکھنا آسان ہوجاتا ہے۔
آخر کار makeZip() تمام تیار کردہ PNG تصاویر کو زپ آرکائیو میں پیک کریں جسے آپ کا براؤزر ڈاؤن لوڈ کرتا ہے۔
یہ آپشن اس وقت مفید ہے جب صارفین پوری اسٹوری بورڈ شیٹس کے بجائے انفرادی پی ڈی ایف صفحہ کی تصویروں کے ساتھ کام کرنا چاہتے ہیں۔


کارکردگی اور اہم تحفظات
بڑے پی ڈی ایف کو پیش کرنا اور ہائی ریزولیوشن امیجز بنانا اہم براؤزر میموری کو استعمال کر سکتا ہے۔
ایپلیکیشن صفحہ پیش نظارہ کیشنگ، عارضی کینوس، پیشرفت کی رپورٹنگ، اور منسوخی کے کنٹرولز کا استعمال کرتے ہوئے اس کام کا انتظام کرتی ہے۔
بہتر نتائج کے لیے، بڑی دستاویزات کے ساتھ کام کرتے وقت فی شیٹ کم پینل استعمال کریں۔ اگر آپ کا اسٹوری بورڈ متعدد پینلز پر مشتمل ہے تو A3 پیپر مزید جگہ بھی فراہم کر سکتا ہے۔
لے آؤٹ کی ترجیحات آپ کے آلے پر یاد رکھی جائیں گی، لیکن پی ڈی ایف اور کیپشن موجودہ براؤزر ٹیب میں ہی رہیں گے۔ ٹیب کو بند کرنے سے پہلے اپنا کام ڈاؤن لوڈ کریں۔
ڈیمو: پی ڈی ایف اسٹوری بورڈ جنریٹر
آپ مکمل شدہ درخواست کو یہاں آزما سکتے ہیں۔
پی ڈی ایف اسٹوری بورڈ جنریٹر - AllInOneTools
اپنی پی ڈی ایف اپ لوڈ کریں، صفحات کو ترتیب دیں، کیپشنز شامل کریں، اپنے اسٹوری بورڈ کو حسب ضرورت بنائیں، اور مکمل نتیجہ ڈاؤن لوڈ کریں۔
نتیجہ
پی ڈی ایف سٹوری بورڈ جنریٹر بنانا کئی مفید براؤزر ٹیکنالوجیز کو ایک ایپلیکیشن میں ملا دیتا ہے۔
PDF.js پی ڈی ایف لوڈنگ اور پیج رینڈرنگ کو ہینڈل کرتا ہے۔ Tesseract.js سکین شدہ صفحات کے لیے منتخب متن کی شناخت فراہم کرتا ہے۔ PDF-lib حتمی سٹوری بورڈ PDF تخلیق کرتا ہے، اور HTML کینوس تصاویر کا پیش نظارہ اور برآمد کرنے کا انتظام کرتا ہے۔
ان اجزاء کو جاوا اسکرپٹ کے ساتھ جوڑ کر، آپ پریزنٹیشن سلائیڈز، مزاحیہ صفحات، اسکرپٹس، اور دیگر پی ڈی ایف دستاویزات کو ترتیب دینے کے لیے عملی ٹولز بنا سکتے ہیں۔
یہ پروجیکٹ یہ بھی ظاہر کرتا ہے کہ کس طرح براؤزر پر مبنی ایپلی کیشن دستاویزات کو مقامی طور پر پروسیس کر سکتی ہے بغیر صارف کو فائلوں کو سرور پر اپ لوڈ کرنے کے۔
ایک مکمل ورک فلو صارفین کو باقاعدہ PDF صفحات کو منظم اسٹوری بورڈ شیٹس میں تبدیل کرنے کی اجازت دیتا ہے جن کا جائزہ لینا، پرنٹ کرنا اور اشتراک کرنا آسان ہے۔