Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by fulvio

Is there any way to disable the scaling of images?

I scale my game size by 3 and obviously any image I load will be scaled by 3 as well. Is there a way to not scale a particular image?

I&039;ve been reading through some posts mentioning: #image.resize(); but I'm not quite sure how to get my head around it.

Thanks in advance.

1 decade ago by fulvio

@ldlework over IRC helped me get started by using an inject against Image.

Here's the code I'm using:

ig.module('game.image-scaling').requires('impact.image')
.defines(function() {
	ig.Image.inject({
		disableScaling: false,
		onload: function( event ) {
			this.width = this.data.width;
			this.height = this.data.height;
			this.loaded = true;

			if (ig.system.scale != 1) {
				if (!this.disableScaling) {
					this.resize(ig.system.scale);
				} else {
					console.log('Disabled ' + ig.system.scale + 'x scaling: ' + this.path);
				}
			}

			if (this.loadCallback) {
				this.loadCallback(this.path, true);
			}
		}
	});
});

I then initialise my images like the following:

this.testImage = new ig.Image('media/background/foo.png');
this.testImage.disableScaling = true;

I can see that the this.resize(ig.system.scale); is ignored, however I can't actually see my image on the canvas anymore. It's disappeared.

Perhaps I've missed something or I'm not understanding how resizing/scaling is meant to behave. Any help would be appreciated in getting this working.

1 decade ago by Graphikos

Instead of not calling resize() at all, maybe just call it with scale of 1.

ig.module('game.image-scaling').requires('impact.image')
.defines(function() {
    ig.Image.inject({
        disableScaling: false,
        onload: function( event ) {
            this.width = this.data.width;
            this.height = this.data.height;
            this.loaded = true;

            if (ig.system.scale != 1) {
                if (!this.disableScaling) {
                    this.resize(ig.system.scale);
                } else {
                    console.log('Disabled ' + ig.system.scale + 'x scaling: ' + this.path);
                    this.resize(1);
                }
            }

            if (this.loadCallback) {
                this.loadCallback(this.path, true);
            }
        }
    });
});

UPDATE: actually looking at the code a bit more, normally impact would skip resize if scale is 1. So maybe that isn't the solution.

My only other guess is that the coordinates are wrong. Using Image.draw() or .drawTile() will probably be applying scale to the position. You might not be seeing it because it's way off the screen. Try drawing at 0,0.

1 decade ago by fulvio

Thanks for the info Graphikos.

Unfortunately drawing at 0,0 still doesn't make the image appear.

This happens with or without the .resize(1); code.

I also noticed that modifying lib/impact/image.js

resize: function( scale ) {
    // scale = 1
	// Nearest-Neighbor scaling
	
	// The original image is drawn into an offscreen canvas of the same size
	// and copied into another offscreen canvas with the new size. 
	// The scaled offscreen canvas becomes the image (data) of this object.
	
	var widthScaled = this.width;// * scale;
	var heightScaled = this.height;// * scale;
    ...
}

By removing the scale multiplication images throughout the application don't even seem to display.

1 decade ago by fulvio

Managed to fix the inject to get it working properly now:

ig.module('game.image-scaling').requires('impact.image')
.defines(function() {
	ig.Image.inject({
		disableScaling: false,
		resize: function( scale ) {
			// Nearest-Neighbor scaling
			
			// The original image is drawn into an offscreen canvas of the same size
			// and copied into another offscreen canvas with the new size. 
			// The scaled offscreen canvas becomes the image (data) of this object.
			
			var widthScaled = this.width * scale;
			var heightScaled = this.height * scale;
			var pixels = null;

			var orig = ig.$new('canvas');
			orig.width = this.width;
			orig.height = this.height;
			var origCtx = orig.getContext('2d');
			origCtx.drawImage( this.data, 0, 0, this.width, this.height, 0, 0, this.width, this.height );
			var origPixels = origCtx.getImageData(0, 0, this.width, this.height);

			var scaled = ig.$new('canvas');
			scaled.width = widthScaled;
			scaled.height = heightScaled;
			var scaledCtx = scaled.getContext('2d');
			var scaledPixels = scaledCtx.getImageData( 0, 0, widthScaled, heightScaled );

			if (this.disableScaling) {
				pixels = origPixels;
			} else {
				for( var y = 0; y < heightScaled; y++ ) {
					for( var x = 0; x < widthScaled; x++ ) {
						var index = (Math.floor(y / scale) * this.width + Math.floor(x / scale)) * 4;
						var indexScaled = (y * widthScaled + x) * 4;
						scaledPixels.data[ indexScaled ] = origPixels.data[ index ];
						scaledPixels.data[ indexScaled+1 ] = origPixels.data[ index+1 ];
						scaledPixels.data[ indexScaled+2 ] = origPixels.data[ index+2 ];
						scaledPixels.data[ indexScaled+3 ] = origPixels.data[ index+3 ];
					}
				}

				pixels = scaledPixels;
			}

			scaledCtx.putImageData( pixels, 0, 0 );

			this.data = scaled;
		}
	});
});

Basically the inject will use the origPixels for the final putImageData as opposed to the scaledPixels.

Example:

/>			</div>
		</div>
	
	
<div class= Page 1 of 1
« first « previous next › last »