Quantcast
Channel: גיקטיים - סטארטאפ והון סיכון
Viewing all articles
Browse latest Browse all 5527

טיפים חשובים לגבי העלאת תמונות מאפליקציית Phonegap ל-S3

$
0
0
phonegap

phonegap

הפוסט נכתב על ידי דורון עודד, מייסד-שותף של הסטארטאפ "Remini", אפליקצית לבניית סיפור החיים של הילד.

לאחרונה השקענו לא מעט זמן ומאמצים בשדרוג רכיב העלאת התמונות באפליקציה שלנו לשרת Amazon S3, וחשבנו לשתף אתכם קצת מהנסיון שלנו.

באפליקציה שלנו (Remini) אחת הפונקציות המרכזיות (אם לא "ה") היא העלאת תמונות לשרת שלנו ב-S3. ומכיוון שהאפליקציה שלנו פותחה ב-Phonegap חיפשנו את הדרך הכי "סטנדרטית" שתהיה נתמכת ע"י כל הפלטפורמות שאנחנו עובדים בהן – אנדרואיד, IOS, ואתר אינטרנט. הדרישות מהתהליך הן כמובן KISS – keep it simple s, שיהיה נתמך ע"י כל הפלטפורמות (במידת האפשר), כיווץ התמונה בצד הלקוח טרם השליחה לשרת, סידור ה-orientation של התמונה (לתמונות המצולמות במכשירי אנדרואיד), ומזעור זמן השליחה למינימום.

אז אם נסקור ממש בקצרה את השיטות הקיימות לשליחת תמונה לשרת מאפליקציית Phonegap נציין 3 אפשרויות:

  1. שליחת קובץ התמונה באמצעות פלאגין ה-file transfer של phonegap.
  2. שליחת קובץ התמונה ב-javascript כ-FormData או XhrHttpRequest2.
  3. שליחת התמונה באמצעות ajax בפורמט base64.

כדי לכווץ את התמונה בצד הלקוח, טרם השליחה, יש 2 אפשרויות: צילום/בחירת התמונה באמצעות פלאגין ה-getPicture של phonegap, שמאפשר לציין את הגודל והרוחב המקסימליים של התמונה, ומחזיר את התמונה מכווצת (בין אם כ-File URI ובין אם כ-base64). או במקרה שהשתמשנו ב- <input type=”file”> הסטנדרטי של html, נאלץ לכווץ את התמונה באמצעות אלמנט ה- <canvas>, ולקבל את התמונה כ- base64.

דבר האחרון שנותר לנו לטפל בו הינו סידור ה-orientation של התמונה באנדרואיד. למי שלא מכיר, למערכת אנדרואיד (לפחות בגרסאותיה הקודמות), יש שיטה ממש "נחמדה" לשמור את התמונות. המערכת תמיד מצלמת ושומרת את התמונה כאילו צולמה כאשר המכשיר מוחזק בצורה ישרה (ללא סיבוב אוטומטי), כלומר שלכאורה תמונות שצילמנו כאשר המכשיר מוחזק ל- "רוחב", ייראו "שוכבות" או "על הצד". אך באנדרואיד בפועל, רואים את התמונות האלה באמת לרוחב, ולא לאורך "על הצד", וזאת בגלל שהמערכת שומרת בקובץ התמונה, Meta data שנקרא exif, ובו מצוין מה ה-orientation בו התמונה צולמה, וכשזו נדרשת להציג את התמונה, היא מסובבת אותה on the fly בהתאם ל-meta data המצוין בה.

לצערנו הרב, השיטה המתוחכמת הזאת, כנראה מתוחכמת מידי עבור מערכת ההפעלה של IOS, שלא השכילה להתייחס לפרמטר ה-orientation, ולכן תמונות שצולמו באנדרואיד "לרוחב", ייראו באייפון לא ב-orientation הנכון – אלא כאילו צולמו "על הצד".

התלבטות נוספת שהייתה לנו היא האם להעלות את התמונות ישירות ל-S3 מהאפליקציה (צד הלקוח), או תחילה לשלוח אותה לשרת ה-php שלנו, ומשם להעלות אותה ל-S3.

היתרונות והחסרונות

אז נפתח ונאמר שבאופן כללי, גם מהנסיון שלנו אישית, וגם מהמלצות מפתחים אחרים, העבודה עם base64 פחות מומלצת מכיוון שמדובר על פורמט "זללני" בזיכרון, שעשוי להוות בעיה במידה ויש לצלם / לבחור מספר גדול יחסית של תמונות, להציג preview שלהם. בנוסף, השליחה של base64 לשרת, גורמת לבקשה להתנפח בכ-20%-30% בנפח.

בואו נתחיל הפוך, ב-gold standard, שהוא צילום/בחירת התמונות בפורמט File URI, כיווצם (שגם לחלק זה אפשר להקדיש פרק נפרד), והעלאתם ישירות ל-S3 מהאפליקציה באמצעות ajax כשהקובץ הנשלח, נשלח כחלק מה- FormData בסוג בקשה XhrHttpRequest2. מבחינתנו הדרך הזו היא הטובה ביותר מכיוון שההעלאה ישירה ל-S3 היא המהירה ביותר (בניגוד לשליחת התמונה לשרת php שלנו, ומשם להעלות ל-S3 ואז לשלוח תשובה שהכל עבר בשלום חזרה לצד הלקוח), ושיטת השליחה (FormData) אינה תלויה ב-plugin כלשהו של phonegap מה שנותן לנו תמיכה בתהליך גם באתר האינטרנט ולא רק באפליקציה ההיברידית.

ועכשיו לבעיות / חסרונות בשיטה הנחמדה הזו. תיקון ה-orientation באנדרואיד נעשה ע"י קריאת ה- exif של הקובץ (באמצעות ספריית javascript כמו זו לדוגמה), ולפי ה-meta data בתמונה, צריך לסובב את התמונה, כך שהיא תהיה ב- orientation הנכון. סיבוב התמונה בצד הלקוח יכול להיעשות רק (לפי הבדיקה שלנו, אבל נשמח להחכים) ע"י האלמנט הסטנדרטי <canvas> ב-html, כפי שמתואר פה. תוצאת התהליך הנ"ל היא base64 של התמונה כאשר היא "מתוקנת" ומסובבת כפי שהיא אמורה להיות.

אגב התהליך הנ"ל לא יעבוד בגרסאות אנדרואיד 2.x בלי זה. אז כבר התהליך מעט נפגע כתוצאה ממעבר ל-base64 במקום file. אך הבעיה המרכזית בתהליך, היא שמסיבה לא ברורה, ה-base64 שנוצר גורם לבקשה (request) לשרת לגדול פי 10 בערך. כלומר אם התמונה ללא ההמרה ל-base64 הייתה אמורה לשקול 60Kb-70Kb, לאחר ההמרה היא תשקול כ-400Kb-500Kb.

בעיה נוספת בתהליך הוא שגרסאות אנדרואיד 2.x לא תומכות ב-XhrHttpRequest2 לפי caniuse.com, ולכן אם אנחנו רוצים לתמוך בגרסאות אלה, אנחנו צריכים להשתמש ב- Phonegap’s file transfer plugin, או לשלוח את התמונה כ-base64 באמצעות ajax.

הפתרון שאנחנו בחרנו, הוא לא לבצע את תיקון ה-orientation בצד הלקוח, שמחייב אותנו באנדרואיד, להמיר את התמונה ל- base64, ולשלוח את התמונה באמצעות ה-file transfer שגם נתמך בגרסאות אנדרואיד 2.x. בפתרון שבחרנו, אנחנו שולחים את התמונה באמצעות ה-file transfer (באנדרואיד), ומבצעים את תיקון ה-orientation ב-php, ולאחר מכן מעלים את התמונה ל-S3, ומחזירים תשובה שהכל סבבה חזרה לצד הלקוח. באייפון ובאינטרנט, אנו שולחים את התמונה באמצעות ה-XhrHttpRequest2 כ-file blob, ושם לא נדרש תיקון orientation.

לסיכום

קשה להסביר את כל החלופות בכתבה אחת, מכיוון שיש מספר שלבים לתהליך, ובכל שלב יש כמה אפשרויות, ולכל אפשרות יש יתרונות וחסרונות. כך שמכפלה של כל השלבים עם כל האפשרויות, יוביל למאמר מאוד ארוך (יותר מהנוכחי), ומאוד משעמם (יותר מהנוכחי). אז ניסינו לתת את האפשרויות שהיו יותר "ריאליות" או יותר פופולריות מבחינתנו, ומה היו השיקולים על קצה המזלג.

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


Viewing all articles
Browse latest Browse all 5527