מטא־נתוני תמונה ותרשום דו־ממד יישומי#

שתי פינות מעשיות של עבודת דו־ממד משלימות את קשת ערכות הכלים. ראשית, קריאת הנתונים שכבר בתוך קובצי תמונה: מידות, פורמט, ובלוק ה־EXIF שמצלמה כותבת. שנית, הסיבה הנפוצה ביותר שאנשים מציירים בכלל, שהיא הפיכת מספרים לתרשים. אף אחת אינה זוהרת, ושתיהן עולות ללא הרף.

קריאת מטא־נתונים: Image::Info#

לפני שאתם מציירים על תמונה או משנים את גודלה, לעיתים קרובות אתם פשוט זקוקים לדעת עליה: כמה היא גדולה, איזה פורמט, מה המצלמה תיעדה. Image::Info הוא Perl טהור, קורא את הכותרות בלי לפענח את התמונה כולה, ומחזיר הפניית hash פשוטה.

use Image::Info qw(image_info dim);

my $info = image_info('photo.jpg');
die $info->{error} if $info->{error};

my ($w, $h) = dim($info);
print "format: $info->{file_media_type}\n";     # image/jpeg
print "size:   ${w}x${h}\n";
print "created: $info->{DateTime}\n" if $info->{DateTime};

dim הוא נוחות המושכת רוחב וגובה מתוך ה־hash. שאר המפתחות תלויים בפורמט ובמה שהקובץ נושא: רזולוציה, סוג צבע, ושדות ה־EXIF הנפוצים לתצלומים. עבור ”מה זה הקובץ הזה“ מהיר זה כל מה שאתם זקוקים לו, וזה עולה כמעט כלום מפני שהוא לעולם אינו מפענח את הפיקסלים.

קריאה וכתיבה של מטא־נתונים: Image::ExifTool#

כשאתם זקוקים למשטח המטא־נתונים המלא, ובמיוחד כשאתם צריכים לכתוב אותו, Image::ExifTool הוא הכלי המכריע. הוא מטפל במטא־נתונים של למעשה כל פורמט תמונה ומדיה, קורא אלפי תגיות, ויכול לערוך אותן במקום בלי לגעת בנתוני התמונה.

use Image::ExifTool qw(:Public);

my $et = Image::ExifTool->new;
$et->ExtractInfo('photo.jpg');

my $model = $et->GetValue('Model');             # camera model
my $when  = $et->GetValue('DateTimeOriginal');
print "shot on $model at $when\n" if $model;

# rewrite a tag and save
$et->SetNewValue('Artist' => 'Jane Doe');
$et->WriteInfo('photo.jpg');                     # edits metadata only

Image::Info עונה על ”כמה גדול, איזה פורמט“ בזול; Image::ExifTool הוא זה שאליו פונים כשהמטא־נתונים עצמם הם המשימה (הסרת תגיות מיקום לפרטיות, תיוג־אצווה של ספריית תמונות, קריאת שדות maker-note). שניהם משאירים את הפיקסלים בשקט.

תרשום: מצב האמנות הכן#

תרשום הוא ציור דו־ממד יישומי: צירים, עמודות, קווים ותוויות המורכבים מהפרימיטיבים שאתם כבר מכירים. נוף התרשום של Perl דליל יותר משהיה פעם. כמה מודולים שהיו פופולריים פעם אינם מתוחזקים כעת, ולכן מקטע זה מוביל עם מה שעדיין עובד ומכנה את השאר בפשטות.

GD::Graph לתרשימי רסטר מהירים#

GD::Graph בנוי על GD ועדיין מתוחזק. הוא הנתיב הקצר ביותר לתרשים עמודות, קו או עוגה כ־PNG. אתם נותנים לו נתונים כקבוצה של מערכים מקבילים (הראשון הוא תוויות ה־x, השאר הם סדרות נתונים) והוא מרַנדֵר.

use GD::Graph::bars;

my @data = (
    ['Jan', 'Feb', 'Mar', 'Apr'],       # x-axis labels
    [  12,    19,    8,     23    ],     # one data series
);

my $chart = GD::Graph::bars->new(400, 300);
$chart->set(
    title       => 'Widgets shipped',
    y_max_value => 25,
    dclrs       => ['blue'],
) or die $chart->error;

my $gd = $chart->plot(\@data) or die $chart->error;

open my $fh, '>', 'chart.png' or die $!;
binmode $fh;
print $fh $gd->png;                      # plot() returns a GD::Image
close $fh;

GD::Graph::bars, ::lines, ::pie ו־::points הם סוסי העבודה. plot מחזיר GD::Image, ולכן כל מה שמפרק GD על פלט חל. זו ברירת המחדל המעשית לתרשים על הדיסק.

SVG לתרשימי ווקטור#

כשהתרשים חייב להישאר חד בכל גודל, או לחיות בדף אינטרנט כתגיות, בנו אותו כ־SVG ישירות. אין הפשטת תרשים ללמוד: אתם מחשבים את מלבני העמודות וקווי הצירים בעצמכם ופולטים אותם. זה יותר קוד מ־GD::Graph, אך הוא בלתי־תלוי־רזולוציה ואינו זקוק לתלות מהודרת.

use SVG;

my @values = (12, 19, 8, 23);
my $svg = SVG->new(width => 400, height => 300);
my $base = 260;                          # baseline y
my $bw   = 60;                           # bar width

for my $i (0 .. $#values) {
    my $h = $values[$i] * 8;             # scale to pixels
    my $x = 40 + $i * ($bw + 20);
    $svg->rect(x => $x, y => $base - $h, width => $bw, height => $h,
               style => { fill => 'steelblue' });
}
$svg->line(x1 => 30, y1 => $base, x2 => 380, y2 => $base,
           style => { stroke => 'black' });

print $svg->xmlify;

עבור כל דבר מעבר לתרשים עמודות או קו פשוט ה־SVG הכתוב־ביד גדל במהירות, אך עבור בדיוק המקרים הנפוצים הוא נקי וחסר־תלויות.

אפשרויות המורשת, נקובות בשם#

שני מודולי תרשום שתמצאו מוזכרים ברשת אינם מתוחזקים למעשה ומצוינים כאן רק כדי שמצבם לא יהיה הפתעה. Chart::Clicker מפיק תרשימים מושכי־עין מרונדרים ב־Cairo אך לא ראה מהדורה שנים ונושא עץ תלויות גדול (כולל Moose); אם אתם כבר מריצים אותו, הוא עובד, אך הוא אינו בחירה לקוד חדש. Chart::Gnuplot מפעיל בינארי gnuplot חיצוני ואף הוא רדום; אם gnuplot מותקן אצלכם ואתם רוצים את כוח השרטוט שלו, קריאה אליו ישירות (או דרך עוטף דק משלכם) ניתנת יותר לתחזוקה מאשר תלות במודול הנטוש. עבור שרטוט מדעי באופן ספציפי, מודולי הגרפיקה של המערכת האקולוגית של PDL הם הנתיב הנתמך יותר ושייכים עם PDL ולא כאן.

היכן זה משאיר את קשת ערכות הכלים#

כעת אתם יכולים ליצור, לטעון, לצייר על, לסנן, לשמור, לווקטר, לבחון ולתרשם תמונות דו־ממד כולן על הדיסק. הדבר האחד החסר הוא מסך: הבאת ציור לתוך חלון חי ואינטראקטיבי. זהו הפרק הבא, והוא גם הגשר לשני פרויקטי הגולה, ששניהם זקוקים לחלון להריץ בו.