cropping image in windows phone - windows-phone-8

windows phone 8 using visual studio
I'm trying to crop an image to 81 piece after i captured it through mobile cam but i found this exception. any help??
int halfWidth = (App.CroppedImage.PixelWidth / 9);
int halfHeight =(App.CroppedImage.PixelHeight / 9);
for (int row = 0; row < 9; row++)
for (int col = 0; col < 9; col++)
{
WriteableBitmap wr = App.CroppedImage.Crop(col * halfHeight, row * halfWidth, halfWidth, halfHeight);
MediaLibrary MLibrary = new MediaLibrary();
IsolatedStorageFileStream IsoStoreFileStreams = myStore.CreateFile("test"+row+col+".jpg");
Extensions.SaveJpeg(wr, IsoStoreFileStreams, 100, 100, 0, 85);
IsoStoreFileStreams.Close();
IsoStoreFileStreams = myStore.OpenFile("test"+ row + col +".jpg", FileMode.Open, FileAccess.Read);
//Add the JPEG file to the photos library on the device.
MediaLibrary libraryy = new MediaLibrary();
Picture picc = library.SavePicture("Saved"+row+col+".jpg", IsoStoreFileStreams);
IsoStoreFileStreams.Close();
}
the exception in this function
Extensions.SaveJpeg(wr, IsoStoreFileStreams, 100, 100, 0, 85);
and the message is
An exception of type 'System.ArgumentException' occurred in Microsoft.Phone.ni.dll but was not handled in user code

stack
sorry i found my error it was `
WriteableBitmap wr = App.CroppedImage.Crop(col * halfWidth, row * halfHeight, halfWidth, halfHeight);
instead
WriteableBitmap wr = App.CroppedImage.Crop(col * halfHeight, row * halfWidth, halfWidth, halfHeight);
`

Related

Detect Colour Using Action Script 3

So I have made a game in scratch which uses the following code block:
I am trying to remake this game in Adobe Animate using Action Script 3 (for a class project), is there a similar way to do this in animate?
It is possible. The trick to do it is to create a tiny-teeny BitmapData object and to draw a small portion of stage under the mouse pointer into that object so that you can obtain the pixel color value.
// BitmapData object and some service objects.
var BD:BitmapData = new BitmapData(3, 3, true);
var R:Rectangle = new Rectangle(0, 0, 3, 3);
var M:Matrix = new Matrix;
// Let's create a TextField so we can output the pixel color value.
var T:TextField = new TextField;
var TF:TextFormat = new TextFormat("_typewriter", 12, 0x000000, true, false, false, null, null, TextFormatAlign.CENTER);
T.x = 10;
T.y = 10;
T.width = 100;
T.height = 18;
T.border = true;
T.background = true;
T.selectable = false;
T.mouseEnabled = false;
T.defaultTextFormat = TF;
addChild(T);
// Lets add some semi-transparent color circles
// so we have colored things to point the mouse at.
for (var i:int = 0; i < 10; i++)
{
var aColor:uint = 0;
aColor |= int(128 + 128 * Math.random()) << 16; // RED
aColor |= int(128 + 128 * Math.random()) << 8; // GREEN
aColor |= int(128 + 128 * Math.random()); // BLUE
var anX:int = stage.stageWidth / 8 + Math.random() * stage.stageWidth * 3 / 4;
var anY:int = stage.stageHeight / 8 + Math.random() * stage.stageHeight * 3 / 4;
var aRadius:int = 50 + 100 * Math.random();
var anAlpha:Number = 0.5 + 0.5 * Math.random();
graphics.beginFill(aColor, anAlpha);
graphics.drawCircle(anX, anY, aRadius);
graphics.endFill();
}
// Now let's watch the mouse every frame.
addEventListener(Event.ENTER_FRAME, onFrame);
function onFrame(e:Event):void
{
// Get pixel color as an RRGGBB String and print it.
T.text = "#" + addZeroes(getColorUnderMouse());
}
function getColorUnderMouse():uint
{
// Adjust Matrix so that we draw the correct piece of screen.
M.tx = -root.mouseX + 1;
M.ty = -root.mouseY + 1;
// Clear the BitmapData and capture the 3x3 piece under the mouse pointer.
BD.fillRect(R, 0xFFFFFFFF);
BD.draw(root, M, null, null, R);
// Read the pixel color value at the center of 3x3 and return it.
return BD.getPixel(1, 1);
}
// This function fixes the hexabinary value with leading
// zeroes if the color value is too small (like 0 = black).
function addZeroes(value:uint, count:uint = 6):String
{
var result:String = value.toString(16).toUpperCase();
while (result.length < count)
{
result = "0" + result;
}
return result;
}

Playing buffer, windows phone 8

I try to play audio buffer in windows phone app.
byte[] buffer = new byte[44100 * 2 * 5];
float t = 0;
for (int i = 0; i < 44100 * 2 * 5; i += 2)
{
short val = (short)(Math.Sin(t * 2 * Math.PI * 440) * short.MaxValue);
buffer[i] = (byte)(val & 0xFF);
buffer[i + 1] = (byte)(val >> 8);
t += 1 / 44100.0f;
}
sf = new SoundEffect(buffer, 44100, AudioChannels.Mono);
// Play.
sf.Play();
i get error:
A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.Xna.Framework.ni.dll
An exception of type 'System.InvalidOperationException' occurred in Microsoft.Xna.Framework.ni.dll but was not handled in user code
Help pls!
You need to call the FrameworkDispatcher.Update.
Same answer as here should work:
Playing a sound from a generated buffer in a Windows phone app

How can I implement Lanczos resampling after every canvas transform without having to make a new canvas?

UPDATE: Once I got this demo working... holy smokes, it's SLOW, like 12-16 seconds for only a level 2 render (when image is around 1000x2000 pixels). This is not even worth bothering with.
I found this really awesome and hopeful looking code in the top answer here: Resizing an image in an HTML5 canvas
//returns a function that calculates lanczos weight
function lanczosCreate(lobes){
return function(x){
if (x > lobes)
return 0;
x *= Math.PI;
if (Math.abs(x) < 1e-16)
return 1
var xx = x / lobes;
return Math.sin(x) * Math.sin(xx) / x / xx;
}
}
//elem: canvas element, img: image element, sx: scaled width, lobes: kernel radius
function thumbnailer(elem, img, sx, lobes){
this.canvas = elem;
elem.width = img.width;
elem.height = img.height;
elem.style.display = "none";
this.ctx = elem.getContext("2d");
this.ctx.drawImage(img, 0, 0);
this.img = img;
this.src = this.ctx.getImageData(0, 0, img.width, img.height);
this.dest = {
width: sx,
height: Math.round(img.height * sx / img.width),
};
this.dest.data = new Array(this.dest.width * this.dest.height * 3);
this.lanczos = lanczosCreate(lobes);
this.ratio = img.width / sx;
this.rcp_ratio = 2 / this.ratio;
this.range2 = Math.ceil(this.ratio * lobes / 2);
this.cacheLanc = {};
this.center = {};
this.icenter = {};
setTimeout(this.process1, 0, this, 0);
}
thumbnailer.prototype.process1 = function(self, u){
self.center.x = (u + 0.5) * self.ratio;
self.icenter.x = Math.floor(self.center.x);
for (var v = 0; v < self.dest.height; v++) {
self.center.y = (v + 0.5) * self.ratio;
self.icenter.y = Math.floor(self.center.y);
var a, r, g, b;
a = r = g = b = 0;
for (var i = self.icenter.x - self.range2; i <= self.icenter.x + self.range2; i++) {
if (i < 0 || i >= self.src.width)
continue;
var f_x = Math.floor(1000 * Math.abs(i - self.center.x));
if (!self.cacheLanc[f_x])
self.cacheLanc[f_x] = {};
for (var j = self.icenter.y - self.range2; j <= self.icenter.y + self.range2; j++) {
if (j < 0 || j >= self.src.height)
continue;
var f_y = Math.floor(1000 * Math.abs(j - self.center.y));
if (self.cacheLanc[f_x][f_y] == undefined)
self.cacheLanc[f_x][f_y] = self.lanczos(Math.sqrt(Math.pow(f_x * self.rcp_ratio, 2) + Math.pow(f_y * self.rcp_ratio, 2)) / 1000);
weight = self.cacheLanc[f_x][f_y];
if (weight > 0) {
var idx = (j * self.src.width + i) * 4;
a += weight;
r += weight * self.src.data[idx];
g += weight * self.src.data[idx + 1];
b += weight * self.src.data[idx + 2];
}
}
}
var idx = (v * self.dest.width + u) * 3;
self.dest.data[idx] = r / a;
self.dest.data[idx + 1] = g / a;
self.dest.data[idx + 2] = b / a;
}
if (++u < self.dest.width)
setTimeout(self.process1, 0, self, u);
else
setTimeout(self.process2, 0, self);
};
thumbnailer.prototype.process2 = function(self){
self.canvas.width = self.dest.width;
self.canvas.height = self.dest.height;
self.ctx.drawImage(self.img, 0, 0);
self.src = self.ctx.getImageData(0, 0, self.dest.width, self.dest.height);
var idx, idx2;
for (var i = 0; i < self.dest.width; i++) {
for (var j = 0; j < self.dest.height; j++) {
idx = (j * self.dest.width + i) * 3;
idx2 = (j * self.dest.width + i) * 4;
self.src.data[idx2] = self.dest.data[idx];
self.src.data[idx2 + 1] = self.dest.data[idx + 1];
self.src.data[idx2 + 2] = self.dest.data[idx + 2];
}
}
self.ctx.putImageData(self.src, 0, 0);
self.canvas.style.display = "block";
}
...
img.onload = function() {
var canvas = document.createElement("canvas");
new thumbnailer(canvas, img, 188, 3); //this produces lanczos3
//but feel free to raise it up to 8. Your client will appreciate
//that the program makes full use of his machine.
document.body.appendChild(canvas);
}
However, this implementation loads an image and renders it, end of story.
I have been trying to re-implement this code so that it does the filtering every time an existing canvas is scaled (think, zooming in and out of an image or document) without having to load a new image or create a new canvas.
How can I adapt it to work this way? Or is that even possible?
What you want to do is something like a singleton to reuse your canvas object. This will let you save the cost of create a new canvas object each time and you will reuse the same object
function getCanvas(){
var canvas;
if (typeof canvas === "undefined"){ canvas = document.createElement("canvas");}
return canvas;
}
img.onload = function() {
var canvas = getCanvas("canvas");
.... THE REST OF YOUR CODE .......
}
.
However this is not what slows your code, image scaling Algorithms are really heavy algorithms with intensive cpu use "usually make use of gpu acceleration at a really low level", and use advanced techniques like multiple bufferr and so others. here is a interesting tutorial in java.net on how image scaling works, it is in java but you can interpolate to any language.
Javascript is not ready for this techniques, so I recommend you to use the transformations available in the canvas api, as in the tutorial you read the efficient way is using the canvas2Dcontext.
var ctx = canvas.getContext("2d");
ctx.scale(2,2);

AIR - Add Images From Drag&Drop To Stage

I'm building a Tile Viewer in Adobe AIR and so far I have implemented the Drag and Drop function that allows the user to load PNG and JPG files.
The function returns a ':File' format, but how can i gram the ':Bitmap' data and place the image in an existing movieclip while looping and make that one tile image repeat in x and y so a preview of a tilemap will shown ?
my thought was to simply add instances of that one file, but i dont know the exact code for that.
( create a Loader, pass the File format to that, and get the BitmapData and place it in place by defining position x and y and also defining width and height. also i want to make instances, to the code doesnt load the image 10 x 10 times )
i would be glad for all helpfull answers.
Edit:
example theory:
( without correct syntax )
image = new ImageFromDropBox(); // bitmap or whatever
for( x = 0; x < 10; x++) {
for( y = 0; y < 10; y++) {
image.x = tilesize * x;
image.y = tileSize * y;
image.width = tileSize;
image.height = tileSize;
stage.addChild( image ); // so each of the 100 places images should be just instances of the ONE LOADED IMAGE
}
}
When working with the File class, you can use the fileInstance.url parameter to load said file in a loader:
var loader:Loader = new Loader();
var urlReq:URLRequest = new URLRequest(file.url);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
loader.load(urlReq);
function loaded(e:Event):void {
var bmp:Bitmap = loader.content as Bitmap
//scale it down and create a scaled down bitmap data for more efficient memory usage
bmp.width = tileSize;
bmp.height = tileSize;
var bData:BitmapData = new BitmapData(tileSize,tileSize); //your new bitmap data
bData.draw(bmp); //capture the scaled down version of the bitmap
//if you don't need the original anymore, dispose of it
bmp.bitmapData.dispose();
var image:Bitmap;
for( var x:int = 0; x < 10; x++) {
for( var y:int = 0; y < 10; y++) {
image = new Bitmap(bmp.bData);
image.x = tilesize * x;
image.y = tileSize * y;
image.width = tileSize;
image.height = tileSize;
stage.addChild( image );
}
}
}

About generating sound waveform in an ActionScript 3 Bitmap

I am generating Bitmap object to show the sound waveform of a loaded sound. The bitmap is 1024x120 and after it has been generated I shrink its size to 655x120. My problem is the player that loads the bitmap in task manager becomes 260MB heavy.
I am also adding some gradients and I also cache it as bitmap, but if I remove this properties I dont get any big difference in size.
I also can try to small its size but still I think the bitmap will be big.
Any idea how to compress or whatever solution to solve this problem?
thanks
Here is some code
These are the sound and Bitmap settigns of the function that generate the bitmap.
public function generateBitmap(snd:Sound):void
{
samples = new ByteArray();
buffer = new BitmapData(1024, 120, false, backColor);
screen = new Bitmap(buffer);
rect = new Rectangle(0, 0, 1, 0);
var left:Number;
var right:Number;
screen.x = 0;
screen.y = 0;
screen.width = 655;
screen.height = 120;
buffer.fillRect( buffer.rect, backColor );
Now I am doing some samples extraction
var extract:Number = Math.floor ((snd.length / 1000) * 44100);
playingTime = snd.length;
ratio = playingTime / buffer.width;
var lng:Number = snd.extract(samples, extract);
samples.position = 0;
step = samples.length / 4096;
do
{
step-- ;
}
while ( step % 4 );
Follows the drawing method of the bitmap.
for (var c:int = 0; c < 4096; c++)
{
rect.x = c / 4;
left = samples.readFloat() * 25;
right = samples.readFloat() * 25;
samples.position = c * step;
// left channel
if (left > 0)
{
rect.y = 30 - left;
rect.height = left;
}
else
{
rect.y = 30;
rect.height = -left;
}
buffer.fillRect( rect, leftChColor );
// right channel
if (right > 0)
{
rect.y = 80 - right;
rect.height = right;
}
else
{
rect.y = 80;
rect.height = -right;
}
buffer.fillRect( rect, rightChColor );
}
screen.width = screenWidth;
screen.height = screenHeight;
addChild( screen );
}
Here is a reference of the code I have used. Tried it without my stuff in the player and get 193MB of RAM just for the flash player. So the code needs I guess the code needs refinement. Any idea or othere method to do the same stuff without eating so much RAM?
Before this line:
buffer = new BitmapData(1024, 120, false, backColor);
Add:
if ( buffer ) { buffer.dispose(); buffer = null; }
buffer = new BitmapData(1024, 120, false, backColor);