Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #20446 from justindarc/bug1014955-v1.4
Browse files Browse the repository at this point in the history
Bug 1014955 - [Camera] Migrate v1.3T downsampling patches to v1.4/master
  • Loading branch information
justindarc committed Jun 12, 2014
2 parents c4d3ff0 + b399182 commit 0539be8
Show file tree
Hide file tree
Showing 17 changed files with 300 additions and 247 deletions.
4 changes: 3 additions & 1 deletion apps/camera/index.html
Expand Up @@ -24,8 +24,10 @@
<!-- <script defer src="/shared/js/media/get_video_rotation.js"></script> -->
<!-- <script defer src="/shared/js/media/video_player.js"></script> -->
<!-- <script defer src="/shared/js/media/media_frame.js"></script> -->
<!-- <script defer src="/shared/js/media/downsample.js"></script> -->
<!-- <script defer src="/shared/js/media/image_size.js"></script> -->
<!-- <script defer src="/shared/js/media/crop_resize_rotate.js"></script> -->
<!-- <script defer src="/shared/js/gesture_detector.js"></script> -->
<!-- <script defer src="/shared/js/lazy_loader.js"></script> -->

<link rel="stylesheet" type="text/css" href="style/main.css" />
</head>
Expand Down
11 changes: 11 additions & 0 deletions apps/camera/js/config/require.js
Expand Up @@ -6,6 +6,9 @@ require.config({
'getVideoRotation': '../shared/js/media/get_video_rotation',
'performanceTesting': '../shared/js/performance_testing_helper',
'jpegMetaDataParser': '../shared/js/media/jpeg_metadata_parser',
'downsample': '../shared/js/media/downsample',
'getImageSize': '../shared/js/media/image_size',
'cropResizeRotate': '../shared/js/media/crop_resize_rotate',
'format': '../shared/js/format',
'GestureDetector': '../shared/js/gesture_detector',
'VideoPlayer': '../shared/js/media/video_player',
Expand Down Expand Up @@ -39,6 +42,14 @@ require.config({
deps: ['BlobView'],
exports: 'parseJPEGMetadata'
},
'getImageSize': {
deps: ['BlobView', 'jpegMetaDataParser'],
exports: 'getImageSize'
},
'cropResizeRotate': {
deps: ['BlobView', 'getImageSize', 'jpegMetaDataParser', 'downsample'],
exports: 'cropResizeRotate'
},
'GestureDetector': {
exports: 'GestureDetector'
},
Expand Down
28 changes: 28 additions & 0 deletions apps/camera/js/config/settings.js
Expand Up @@ -17,6 +17,18 @@ module.exports = {
// even on hardware that supports it.
disabled: false
},
previewGallery: {

// Flag for determining if the preview should limit the
// image size to the value of CONFIG_MAX_IMAGE_PIXEL_SIZE
// (enable for devices with limited memory)
limitMaxPreviewSize: false,

// Dimensions for thumbnail image (will automatically be
// multiplied by the devicePixelRatio)
thumbnailWidth: 54,
thumbnailHeight: 54
},
viewfinder: {
scaleType: 'fill'
},
Expand All @@ -43,6 +55,22 @@ module.exports = {
],
persistent: false
},
activity: {

// Reduce the size of images returned by pick activities.
// A pick activity can specify its own maximum size. However,
// this setting can lower that pixel size limitation even
// further. To prevent further limiting the pixel size for
// pick activities, set this value to `0`.
// (useful for devices with limited memory)
maxPickPixelSize: 0,

// Reduce the size of images returned by share activities.
// To prevent resizing images that are shared, set this
// value to `0`.
// (useful for devices with limited memory)
maxSharePixelSize: 0
},
loadingScreen: {
delay: 600
},
Expand Down
20 changes: 14 additions & 6 deletions apps/camera/js/controllers/confirm.js
Expand Up @@ -9,7 +9,7 @@ define(function(require, exports, module) {

var prepareBlob = require('lib/prepare-preview-blob');
var debug = require('debug')('controller:confirm');
var resizeImage = require('lib/resize-image');
var resizeImageAndSave = require('lib/resize-image-and-save');
var ConfirmView = require('views/confirm');
var bindAll = require('lib/bind-all');

Expand All @@ -26,10 +26,11 @@ module.exports.ConfirmController = ConfirmController;
* @param {Object} options
*/
function ConfirmController(app) {
this.app = app;
this.settings = app.settings;
this.activity = app.activity;
this.camera = app.camera;
this.container = app.el;
this.app = app;

// Allow these dependencies
// to be injected if need be.
Expand All @@ -51,8 +52,15 @@ ConfirmController.prototype.renderView = function() {
return;
}

// Check whether the MediaFrame should limit the pixel size.
var maxPreviewSize =
this.settings.previewGallery.get('limitMaxPreviewSize') ?
window.CONFIG_MAX_IMAGE_PIXEL_SIZE : 0;

this.confirmView = new this.ConfirmView();
this.confirmView.maxPreviewSize = maxPreviewSize;
this.confirmView.render().appendTo(this.container);

this.confirmView.on('click:select', this.onSelectMedia);
this.confirmView.on('click:retake', this.onRetakeMedia);
};
Expand Down Expand Up @@ -112,12 +120,12 @@ ConfirmController.prototype.onSelectMedia = function() {
needsResizing = activity.data.width || activity.data.height;
debug('needs resizing: %s', needsResizing);
if (needsResizing) {
resizeImage({
blob: this.newMedia.blob,
resizeImageAndSave({
blob: media.blob,
width: activity.data.width,
height: activity.data.height
}, function(newBlob) {
media.blob = newBlob;
}, function(resizedBlob) {
media.blob = resizedBlob;
activity.postResult(media);
});
return;
Expand Down
128 changes: 89 additions & 39 deletions apps/camera/js/controllers/preview-gallery.js
Expand Up @@ -10,17 +10,10 @@ var bindAll = require('lib/bind-all');
var PreviewGalleryView = require('views/preview-gallery');
var createThumbnailImage = require('lib/create-thumbnail-image');
var preparePreview = require('lib/prepare-preview-blob');
var resizeImageAndSave = require('lib/resize-image-and-save');
var StringUtils = require('lib/string-utils');
var CustomDialog = require('CustomDialog');

/**
* The size of the thumbnail images we generate.
*
* XXX: these constants are linked to style/controls.css, and should
* probably be defined somewhere else in the app.
*/
var THUMBNAIL_WIDTH = 54 * window.devicePixelRatio;
var THUMBNAIL_HEIGHT = 54 * window.devicePixelRatio;

/**
* Exports
*/
Expand All @@ -32,7 +25,9 @@ function PreviewGalleryController(app) {
debug('initializing');
bindAll(this);
this.app = app;
this.settings = app.settings;
this.storage = this.app.storage;
this.resizeImageAndSave = resizeImageAndSave;
this.bindEvents();
this.configure();
debug('initialized');
Expand All @@ -50,6 +45,12 @@ PreviewGalleryController.prototype.configure = function() {
this.currentItemIndex = 0;
this.items = []; // All the pictures and videos we know about
this.thumbnailItem = null; // The item that currently has a thumbnail

var dpr = window.devicePixelRatio;
this.thumbnailSize = {
width: this.settings.previewGallery.get('thumbnailWidth') * dpr,
height: this.settings.previewGallery.get('thumbnailHeight') * dpr
};
};

PreviewGalleryController.prototype.openPreview = function() {
Expand All @@ -58,10 +59,18 @@ PreviewGalleryController.prototype.openPreview = function() {
return;
}

if (this.view) { return; }
this.view = new PreviewGalleryView()
.render()
.appendTo(this.app.el);
if (this.view) {
return;
}

// Check whether the MediaFrame should limit the pixel size.
var maxPreviewSize =
this.settings.previewGallery.get('limitMaxPreviewSize') ?
window.CONFIG_MAX_IMAGE_PIXEL_SIZE : 0;

this.view = new PreviewGalleryView();
this.view.maxPreviewSize = maxPreviewSize;
this.view.render().appendTo(this.app.el);

this.view.on('click:gallery', this.onGalleryButtonClick);
this.view.on('click:share', this.shareCurrentItem);
Expand Down Expand Up @@ -139,21 +148,43 @@ PreviewGalleryController.prototype.shareCurrentItem = function() {
var index = this.currentItemIndex;
var item = this.items[index];
var type = item.isVideo ? 'video/*' : 'image/*';
var filename = item.filepath.substring(
item.filepath.lastIndexOf('/') + 1);
var activity = new window.MozActivity({
name: 'share',
data: {
type: type,
number: 1,
blobs: [item.blob],
filenames: [filename],
filepaths: [item.filepath] /* temporary hack for bluetooth app */
}
});
activity.onerror = function(e) {
console.warn('Share activity error:', activity.error.name);
var filename = StringUtils.lastPathComponent(item.filepath);

var launchShareActivity = function(blob) {
var activity = new window.MozActivity({
name: 'share',
data: {
type: type,
number: 1,
blobs: [blob],
filenames: [filename],
filepaths: [item.filepath] /* temporary hack for bluetooth app */
}
});
activity.onerror = function(e) {
console.warn('Share activity error:', activity.error.name);
};
};

if (item.isVideo) {
launchShareActivity(item.blob);
return;
}

var self = this;

this.stopItemDeletedEvent = true;

// Resize the image to the maximum pixel size for share activities.
// If no maximum is specified (value is `0`), then simply rotate
// (if needed) and re-save the image prior to launching the activity.
this.resizeImageAndSave({
blob: item.blob,
size: this.settings.activity.get('maxSharePixelSize')
}, function(resizedBlob) {
self.stopItemDeletedEvent = false;
launchShareActivity(resizedBlob);
});
};

/**
Expand Down Expand Up @@ -302,6 +333,13 @@ PreviewGalleryController.prototype.previewItem = function() {
* @param {Object} filepath
*/
PreviewGalleryController.prototype.onItemDeleted = function(data) {

// Check if this event is being stopped such as in the case
// of resizing an image for a share activity.
if (this.stopItemDeletedEvent) {
return;
}

var deleteIdx = -1;
var deletedFilepath = data.path;

Expand Down Expand Up @@ -338,34 +376,46 @@ PreviewGalleryController.prototype.onBlur = function() {
PreviewGalleryController.prototype.updateThumbnail = function() {
var self = this;
var media = this.thumbnailItem = this.items[0] || null;
var blob;

if (media === null) {
this.app.emit('newthumbnail', null);
return;
}

if (media.isVideo) {

// If it is a video we can create a thumbnail from the poster image
createThumbnailImage(media.poster.blob, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT,
media.rotation, media.mirrored, gotThumbnail);
blob = media.poster.blob;
} else {

// If it is a photo we want to use the EXIF preview rather than
// decoding the whole image if we can.
var blob;
if (media.preview) {
// If JPEG contains a preview we use it to create the thumbnail
blob = media.blob.slice(media.preview.start, media.preview.end,
'image/jpeg');
} else {
// Otherwise, use the full-size image
blob = media.blob;
}

createThumbnailImage(blob, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT,
media.rotation, media.mirrored, gotThumbnail);
// The Tarako may produce EXIF previews that have the wrong
// aspect ratio and are distorted. Check for that, and if the
// aspect ratio is not right, then create a thumbnail from the
// full size image
var fullRatio = media.width / media.height;
var previewRatio = media.preview.width / media.preview.height;

// If aspect ratios match, create thumbnail from EXIF preview
if (Math.abs(fullRatio - previewRatio) < 0.01) {
blob = media.blob.slice(media.preview.start, media.preview.end,
'image/jpeg');
}
}

// If a thumbnail couldn't be obtained from the EXIF preview,
// use the full image
if (!blob) {
blob = media.blob;
}
}

createThumbnailImage(blob, media, this.thumbnailSize, gotThumbnail);

function gotThumbnail(blob) {
self.app.emit('newthumbnail', blob);
}
Expand Down

0 comments on commit 0539be8

Please sign in to comment.