Jump to content

Video and image croping in PIXI.JS


martiniti
 Share

Recommended Posts

Hello everyone!

Maybe someone has experience and can share with it.

The question is how you guys croping media content inside PIXI Application.

I have a lot of different stock video and images with different sizes.

User can choose aspect ratio of final result: landscape (1920x1080), square (1080x1080), vertical (607,5x1080).

The size of main container always is 1920x1080.

Also there should be good resolution, let`s say: PIXI.settings.RESOLUTION = 2;

I made some images to demonstrate how I want to make it.

For example, user can choose vertical ratio and with horizontal hd video (or hd image) - so video (image) should be cropped, and around this video (image) should be for example black (or can be else) color.

My code is:

const video = some_json_data;

const videoContainer = document.getElementById('videoContainer');

switch (video.aspectRatio){

  case "square":

  vw = 1080;
  vh = 1080;

  break;

  case "landscape":

  vw = 1920;
  vh = 1080;

  break;

  case "vertical":

  vw = 607.5;
  vh = 1080;

  break;

  default:

  break;

}

const bgColor = '0x000000';

PIXI.settings.RESOLUTION = 2;

app = new PIXI.Application({
  width: vw,
  height: vh,
  backgroundColor: bgColor,
});

videoContainer.appendChild(app.view);

const renderer = PIXI.autoDetectRenderer({ width: vw, height: vh, resolution: 2 });

renderer.view.style.width = `${vw}px`;
renderer.view.style.height = `${vh}px`;

// create the root of the scene graph
const stage = new PIXI.Container();

app.stage.addChild(stage);

videoBg = PIXI.Texture.from(videoUrl);
videoSprite = new PIXI.Sprite(videoBg);
const videoController = videoSprite._texture.baseTexture.resource.source;

app.stage.addChild(videoSprite);

videoBg.baseTexture.resource.source.loop = false;
videoBg.baseTexture.resource.autoPlay = false;

// Width
videoSprite.width = vw;
videoSprite.height = vh;

// move the sprite to the center of the screen
videoSprite.alpha = 1;
videoSprite.anchor.set(.5);
videoSprite.x = app.screen.width / 2;
videoSprite.y = app.screen.height / 2;


app.ticker.add(function () {

	// render the stage
	renderer.render(stage);

});

 

 

hor.jpg

square.jpg

ver.jpg

Link to comment
Share on other sites

Hey guys!

I have solution for those who searching answers for this question. But I still have one question.

First of all you need to create canvas exactly with sizes that you want.

For example for square proportion you can set vw (1080) x vh (1080)

PIXI.settings.RESOLUTION = 2;

app = new PIXI.Application({
  width: vw,
  height: vh,
  backgroundColor: bgColor,
});

videoContainer.appendChild(app.view);

const renderer = PIXI.autoDetectRenderer({ width: vw, height: vh, resolution: 2 });

renderer.view.style.width = `${vw}px`;
renderer.view.style.height = `${vh}px`;

Then I just removed sprite width and height.

And the last important thing is set correctly your canvas css parameters. So if you have square proportions just set it up for example:

'&.square > canvas': {
  width: 600,
  height: 600
}

And thats it folks :)

Link to comment
Share on other sites

Here is my next question.

Thats all great if you not using a PIXI.Filter.

Unfortnatelly autoFit parameter deformate my media content with size of application.

I noticed that autoFit based on bounds of canvas and fit my images/videos according to canvas size.

Is there way to autoFit for example by maxHeight and by maxWidth sizes of canvas?

Link to comment
Share on other sites

yes, hack FilterSystem, override push() function like i did in pixi-picture.

 

though i think there's easier solution for your problem. Its just there's really no good way to do that - if there was, we could already add that layout in pixi! Of course, maybe people noticed it and didnt want to make PR...

Edited by ivan.popelyshev
Link to comment
Share on other sites

Hello guys!

Finally I found and make some hacks with PIXI code, thank you Ivan so much for your support!

But I still have a little question. For my hacks I used pixi-legacy.js file inside test environment.

For my current project I using NPM system with node_modules. How can I hack them? There are a lot of similars files, also pixi-legacy.js that load @pixi have some core files too.

I tryed make some tracing with console.log(''Olololo ?");   to understand what exactly should I patch but still have no effect...

 

Below I share my solution:

Inside this function FilterSystem.prototype.push = function (target, filters) I added 3 new parameters under "var autoFit = filters[0].autoFit;" :

var autoFit = filters[0].autoFit;
var autoFitY = filters[0].autoFitY;
var autoFitWidth = filters[0].autoFitWidth;
var autoFitHeight = filters[0].autoFitHeight;

After if(autoFit){...} I wrote this code:

//Autofit by height
if (autoFitY) {
  var sourceFrameProjected = this.tempRect.copyFrom(renderTextureSystem.sourceFrame);
  // Project source frame into world space (if projection is applied)
  if (renderer.projection.transform) {
  	this.transformAABB(tempMatrix.copyFrom(renderer.projection.transform).invert(), sourceFrameProjected);
  }
  state.sourceFrame.fitY(sourceFrameProjected, autoFitWidth, autoFitHeight);
}

Also I wrote this function. You can add it under Rectangle.prototype.fit =  function (rectangle) :

/**
* Fits by height with determined width and height.
*
* @param {PIXI.Rectangle} rectangle - The rectangle to fit.
* @return {PIXI.Rectangle} Returns itself.
*/
Rectangle.prototype.fitY = function (rectangle, width, height) {
  this.x = (rectangle.width - width)/2;
  this.y = Math.max(this.y, rectangle.y);
  this.width = width;
  this.height = height;
  return this;
};

In my previous answer I made mistake you do need to set your stage width and height with your video or image width and height!!!

Hope this will help someone.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...