Skip to content

Commit

Permalink
resolve merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
David Flanagan committed Feb 17, 2013
1 parent 5e064fb commit 53959d7
Show file tree
Hide file tree
Showing 11 changed files with 527 additions and 357 deletions.
193 changes: 121 additions & 72 deletions apps/camera/js/filmstrip.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ var Filmstrip = (function() {
frame.displayImage(item.blob, item.width, item.height, item.preview);
}
else if (item.isVideo) {
frame.displayVideo(item.blob, item.width, item.height, item.rotation);
frame.displayVideo(item.blob, item.poster,
item.width, item.height,
item.rotation);
}

preview.classList.remove('offscreen');
Expand Down Expand Up @@ -328,18 +330,17 @@ var Filmstrip = (function() {

offscreenImage.src = URL.createObjectURL(previewBlob);
offscreenImage.onload = function() {
createThumbnailFromElement(offscreenImage, false, 0,
function(thumbnail) {
addItem({
isImage: true,
filename: filename,
thumbnail: thumbnail,
blob: blob,
width: metadata.width,
height: metadata.height,
preview: metadata.preview
});
});
createThumbnailFromImage(offscreenImage, function(thumbnail) {
addItem({
isImage: true,
filename: filename,
thumbnail: thumbnail,
blob: blob,
width: metadata.width,
height: metadata.height,
preview: metadata.preview
});
});
URL.revokeObjectURL(offscreenImage.src);
offscreenImage.onload = null;
offscreenImage.src = null;
Expand Down Expand Up @@ -378,18 +379,19 @@ var Filmstrip = (function() {
}

offscreenVideo.onloadedmetadata = function() {
createThumbnailFromElement(offscreenVideo, true, rotation,
function(thumbnail) {
addItem({
isVideo: true,
filename: filename,
thumbnail: thumbnail,
blob: blob,
width: offscreenVideo.videoWidth,
height: offscreenVideo.videoHeight,
rotation: rotation
});
createThumbnailFromVideo(offscreenVideo, rotation, filename,
function(thumbnail, poster) {
addItem({
isVideo: true,
filename: filename,
thumbnail: thumbnail,
poster: poster,
blob: blob,
width: offscreenVideo.videoWidth,
height: offscreenVideo.videoHeight,
rotation: rotation
});
});
URL.revokeObjectURL(url);
offscreenVideo.onerror = null;
offscreenVideo.onloadedmetadata = null;
Expand Down Expand Up @@ -444,16 +446,16 @@ var Filmstrip = (function() {
// Create a thumbnail size canvas, copy the <img> or <video> into it
// cropping the edges as needed to make it fit, and then extract the
// thumbnail image as a blob and pass it to the callback.
function createThumbnailFromElement(elt, video, rotation, callback) {
function createThumbnailFromImage(img, callback) {
// Create a thumbnail image
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = THUMBNAIL_WIDTH;
canvas.height = THUMBNAIL_HEIGHT;
var eltwidth = video ? elt.videoWidth : elt.width;
var eltheight = video ? elt.videoHeight : elt.height;
var scalex = canvas.width / eltwidth;
var scaley = canvas.height / eltheight;
var imgwidth = img.width;
var imgheight = img.height;
var scalex = canvas.width / imgwidth;
var scaley = canvas.height / imgheight;

// Take the larger of the two scales: we crop the image to the thumbnail
var scale = Math.max(scalex, scaley);
Expand All @@ -462,69 +464,116 @@ var Filmstrip = (function() {
// canvas to create the thumbnail
var w = Math.round(THUMBNAIL_WIDTH / scale);
var h = Math.round(THUMBNAIL_HEIGHT / scale);
var x = Math.round((eltwidth - w) / 2);
var y = Math.round((eltheight - h) / 2);
var x = Math.round((imgwidth - w) / 2);
var y = Math.round((imgheight - h) / 2);

// Draw that region of the image into the canvas, scaling it down
context.drawImage(img, x, y, w, h,
0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);

canvas.toBlob(callback, 'image/jpeg');
}

// Create a thumbnail size canvas, copy the <img> or <video> into it
// cropping the edges as needed to make it fit, and then extract the
// thumbnail image as a blob and pass it to the callback.
function createThumbnailFromVideo(video, rotation, filename, callback) {
var videowidth = video.videoWidth;
var videoheight = video.videoHeight;

// First, create a full-size unrotated poster image
var postercanvas = document.createElement('canvas');
var postercontext = postercanvas.getContext('2d');
postercanvas.width = videowidth;
postercanvas.height = videoheight;
postercontext.drawImage(video, 0, 0);

// Now create a thumbnail
var thumbnailcanvas = document.createElement('canvas');
var thumbnailcontext = thumbnailcanvas.getContext('2d');
thumbnailcanvas.width = THUMBNAIL_WIDTH;
thumbnailcanvas.height = THUMBNAIL_HEIGHT;

var scalex = THUMBNAIL_WIDTH / videowidth;
var scaley = THUMBNAIL_HEIGHT / videoheight;

// Take the larger of the two scales: we crop the image to the thumbnail
var scale = Math.max(scalex, scaley);

// Calculate the region of the image that will be copied to the
// canvas to create the thumbnail
var w = Math.round(THUMBNAIL_WIDTH / scale);
var h = Math.round(THUMBNAIL_HEIGHT / scale);
var x = Math.round((videowidth - w) / 2);
var y = Math.round((videoheight - h) / 2);

// If a rotation is specified, rotate the canvas context
if (rotation) {
context.save();
thumbnailcontext.save();
switch (rotation) {
case 90:
context.translate(THUMBNAIL_WIDTH, 0);
context.rotate(Math.PI / 2);
thumbnailcontext.translate(THUMBNAIL_WIDTH, 0);
thumbnailcontext.rotate(Math.PI / 2);
break;
case 180:
context.translate(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
context.rotate(Math.PI);
thumbnailcontext.translate(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
thumbnailcontext.rotate(Math.PI);
break;
case 270:
context.translate(0, THUMBNAIL_HEIGHT);
context.rotate(-Math.PI / 2);
thumbnailcontext.translate(0, THUMBNAIL_HEIGHT);
thumbnailcontext.rotate(-Math.PI / 2);
break;
}
}

// Draw that region of the image into the canvas, scaling it down
context.drawImage(elt, x, y, w, h,
0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
// Draw that region of the poster into the thumbnail, scaling it down
thumbnailcontext.drawImage(postercanvas, x, y, w, h,
0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);

// Restore the default rotation so the play arrow comes out correctly
if (rotation) {
context.restore();
thumbnailcontext.restore();
}

// If this is a video, superimpose a translucent play button over
// the captured video frame to distinguish it from a still photo thumbnail
if (video) {
// First draw a transparent gray circle
context.fillStyle = 'rgba(0, 0, 0, .3)';
context.beginPath();
context.arc(THUMBNAIL_WIDTH / 2, THUMBNAIL_HEIGHT / 2,
THUMBNAIL_HEIGHT / 3, 0, 2 * Math.PI, false);
context.fill();

// Now outline the circle in white
context.strokeStyle = 'rgba(255,255,255,.6)';
context.lineWidth = 2;
context.stroke();

// And add a white play arrow.
context.beginPath();
context.fillStyle = 'rgba(255,255,255,.6)';
// The height of an equilateral triangle is sqrt(3)/2 times the side
var side = THUMBNAIL_HEIGHT / 3;
var triangle_height = side * Math.sqrt(3) / 2;
context.moveTo(THUMBNAIL_WIDTH / 2 + triangle_height * 2 / 3,
THUMBNAIL_HEIGHT / 2);
context.lineTo(THUMBNAIL_WIDTH / 2 - triangle_height / 3,
THUMBNAIL_HEIGHT / 2 - side / 2);
context.lineTo(THUMBNAIL_WIDTH / 2 - triangle_height / 3,
THUMBNAIL_HEIGHT / 2 + side / 2);
context.closePath();
context.fill();
// the captured video frame to distinguish it from a still photo
// thumbnail. First draw a transparent gray circle
thumbnailcontext.fillStyle = 'rgba(0, 0, 0, .3)';
thumbnailcontext.beginPath();
thumbnailcontext.arc(THUMBNAIL_WIDTH / 2, THUMBNAIL_HEIGHT / 2,
THUMBNAIL_HEIGHT / 3, 0, 2 * Math.PI, false);
thumbnailcontext.fill();

// Now outline the circle in white
thumbnailcontext.strokeStyle = 'rgba(255,255,255,.6)';
thumbnailcontext.lineWidth = 2;
thumbnailcontext.stroke();

// And add a white play arrow.
thumbnailcontext.beginPath();
thumbnailcontext.fillStyle = 'rgba(255,255,255,.6)';
// The height of an equilateral triangle is sqrt(3)/2 times the side
var side = THUMBNAIL_HEIGHT / 3;
var triangle_height = side * Math.sqrt(3) / 2;
thumbnailcontext.moveTo(THUMBNAIL_WIDTH / 2 + triangle_height * 2 / 3,
THUMBNAIL_HEIGHT / 2);
thumbnailcontext.lineTo(THUMBNAIL_WIDTH / 2 - triangle_height / 3,
THUMBNAIL_HEIGHT / 2 - side / 2);
thumbnailcontext.lineTo(THUMBNAIL_WIDTH / 2 - triangle_height / 3,
THUMBNAIL_HEIGHT / 2 + side / 2);
thumbnailcontext.closePath();
thumbnailcontext.fill();

// Save the poster image to storage, then call the callback
postercanvas.toBlob(savePosterImage, 'image/jpeg');

// The Gallery app depends on this poster image being saved here
function savePosterImage(poster) {
Camera._pictureStorage.addNamed(poster, filename.replace('.3gp', '.jpg'));
thumbnailcanvas.toBlob(function(thumbnail) {
callback(thumbnail, poster);
}, 'image/jpeg');
}

canvas.toBlob(callback, 'image/jpeg');
}

function setOrientation(orientation) {
Expand Down
2 changes: 1 addition & 1 deletion apps/camera/style/VideoPlayer.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* styles for the video element itself */
.videoPlayer {
.videoPoster, .videoPlayer {
position: absolute;
left: 0; /* we position it with a transform */
top:0;
Expand Down
Loading

0 comments on commit 53959d7

Please sign in to comment.