Capture element shows 90 degree preview in windows phone 8.1 - windows-phone-8.1

I have following code for capture element in my xaml.
<CaptureElement Width="400" Height="400" x:Name="cameraCapture" Stretch="UniformToFill" Margin="0,0,0,40">
</CaptureElement>
My page loaded
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
await captureManager.InitializeAsync();
cameraCapture.Source = captureManager;
await captureManager.StartPreviewAsync();
}
in preview it shows rotated image
if I set rotation to preview than in view it works fine but saved image is still rotated to 90 degree. How can I fix this?
captureManager.SetPreviewRotation(VideoRotation.Clockwise90Degrees);

After you call CapturePhotoToStreamAsync you should apply these things on the stream:
//create decoder and encoder
BitmapDecoder dec = await BitmapDecoder.CreateAsync(imageStream);
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(imageStream, dec);
//roate the image
enc.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;
//write changes to the image stream
await enc.FlushAsync();
It's just a snippet, but I guess you get the idea.
For full code sample take a look here: https://dzone.com/articles/how-capture-photo-your-windows-0

Related

"Tainted canvases may not be loaded" Cross domain issue with WebGL textures

I've learnt a lot in the last 48 hours about cross domain policies, but apparently not enough.
Following on from this question. My HTML5 game supports Facebook login. I'm trying to download profile pictures of people's friends. In the HTML5 version of my game I get the following error in Chrome.
detailMessage: "com.google.gwt.core.client.JavaScriptException:
(SecurityError) ↵ stack: Error: Failed to execute 'texImage2D' on
'WebGLRenderingContext': Tainted canvases may not be loaded.
As I understand it, this error occurs because I'm trying to load an image from a different domain, but this can be worked around with an Access-Control-Allow-Origin header, as detailed in this question.
The URL I'm trying to download from is
https://graph.facebook.com/1387819034852828/picture?width=150&height=150
Looking at the network tab in Chrome I can see this has the required access-control-allow-origin header and responds with a 302 redirect to a new URL. That URL varies, I guess depending on load balancing, but here's an example URL.
https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xap1/v/t1.0-1/c0.0.160.160/p160x160/11046398_1413754142259317_606640341449680402_n.jpg?oh=6738b578bc134ff207679c832ecd5fe5&oe=562F72A4&gda=1445979187_2b0bf0ad3272047d64c7bfc2dbc09a29
This URL also has the access-control-allow-origin header. So I don't understand why this is failing.
Being Facebook, and the fact that thousands of apps, games and websites display users profile pictures, I'm assuming this is possible. I'm aware that I can bounce through my own server, but I'm not sure why I should have to.
Answer
I eventually got cross domain image loading working in libgdx with the following code (which is pretty hacky and I'm sure can be improved). I've not managed to get it working with the AssetDownloader yet. I'll hopefully work that out eventually.
public void downloadPixmap(final String url, final DownloadPixmapResponse response) {
final RootPanel root = RootPanel.get("embed-html");
final Image img = new Image(url);
img.getElement().setAttribute("crossOrigin", "anonymous");
img.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
HtmlLauncher.application.getPreloader().images.put(url, ImageElement.as(img.getElement()));
response.downloadComplete(new Pixmap(Gdx.files.internal(url)));
root.remove(img);
}
});
root.add(img);
}
interface DownloadPixmapResponse {
void downloadComplete(Pixmap pixmap);
void downloadFailed(Throwable e);
}
are you setting the crossOrigin attribute on your img before requesting it?
var img = new Image();
img.crossOrigin = "anonymous";
img.src = "https://graph.facebook.com/1387819034852828/picture?width=150&height=150";
It's was working for me when this question was asked. Unfortunately the URL above no longer points to anything so I've changed it in the example below
var img = new Image();
img.crossOrigin = "anonymous"; // COMMENT OUT TO SEE IT FAIL
img.onload = uploadTex;
img.src = "https://i.imgur.com/ZKMnXce.png";
function uploadTex() {
var gl = document.createElement("canvas").getContext("webgl");
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
try {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
log("DONE: ", gl.getError());
} catch (e) {
log("FAILED to use image because of security:", e);
}
}
function log() {
var div = document.createElement("div");
div.innerHTML = Array.prototype.join.call(arguments, " ");
document.body.appendChild(div);
}
<body></body>
How to check you're receiving the headers
Open your devtools, pick the network tab, reload the page, select the image in question, look at both the REQUEST headers and the RESPONSE headers.
The request should show your browser sent an Origin: header
The response should show you received
Access-Control-Allow-Methods: GET, OPTIONS, ...
Access-Control-Allow-Origin: *
Note, both the response AND THE REQUEST must show the entries above. If the request is missing Origin: then you didn't set img.crossOrigin and the browser will not let you use the image even if the response said it was ok.
If your request has the Origin: header and the response does not have the other headers than that server did not give permission to use the image to display it. In other words it will work in an image tag and you can draw it to a canvas but you can't use it in WebGL and any 2d canvas you draw it into will become tainted and toDataURL and getImageData will stop working
this is a classic crossdomain issue that happens when you're developing locally.
I use python's simple server as a quick fix for this.
navigate to your directory in the terminal, then type:
$ python -m SimpleHTTPServer
and you'll get
Serving HTTP on 0.0.0.0 port 8000 ...
so go to 0.0.0.0:8000/ and you should see the problem resolved.
You can base64 encode your texture.

record video by front-camera - WP8 - C#

My windows phone app needs to record a video from front-camera and send it to the server through a webservice.
Here while I'm trying to record video from front-camera, I'm getting mirror inverted video. Means front-camera records 180 degree rotated video.
what i think probably the only solution of it is to rotate the recorded video stream to 180 degree back.
Question:
is there any other solution to record proper video by front-camera in wp8?
if not, how to rotate the video stream 180 degree? any c# API to do it..?
Edit:
Here is code that I'm using:
XAML code for VideoBrush
<Canvas x:Name="CanvasLayoutRoot" RenderTransformOrigin="0.5 0.5"
Width="{Binding ActualHeight, ElementName=LayoutRoot}"
Height="{Binding ActualWidth, ElementName=LayoutRoot}"
Margin="-160 0 0 0">
<!--Background="Transparent"-->
<Canvas.Background>
<VideoBrush x:Name="videoBrush" />
</Canvas.Background>
<Canvas.RenderTransform>
<RotateTransform x:Name="rt" />
</Canvas.RenderTransform>
</Canvas>
Initializing camera
public async void InitializeVideoRecorder()
{
try
{
if (videoCapture == null)
{
// below line of code will detect if "Front Camera" is available or not
// if availble, then open it or it will open "Back Camera"
videoCapture = await AudioVideoCaptureDevice.OpenAsync(
AudioVideoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Front) ? CameraSensorLocation.Front : CameraSensorLocation.Back,
new Windows.Foundation.Size(640, 480));
videoCapture.RecordingFailed += videoCapture_RecordingFailed;
videoCapture.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, videoCapture.SensorRotationInDegrees);
// Initialize the camera if it exists on the phone.
if (videoCapture != null)
{
videoBrush.SetSource(videoCapture);
if (!AudioVideoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Front))
{
rt.Angle = videoCapture.SensorRotationInDegrees;
}
else
{
rt.Angle = -(videoCapture.SensorRotationInDegrees);
}
}
else
{
MessageBox.Show("Unable to load Camera. Please try again later.", App.appName, MessageBoxButton.OK);
NavigationService.GoBack();
}
}
}
catch (Exception ex)
{
(new WebServices()).catchExceptions(ex);
NavigationService.GoBack();
}
}
Starting VideoCapture
private async Task StartVideoRecording()
{
try
{
// Gets the application data folder
StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
StorageFolder transfersFolder = await (await applicationFolder.GetFolderAsync("Shared")).GetFolderAsync("Transfers");
// Create the file specified in the application data folder
videoFileName = selectedQue.response.template_id + "_" + selectedQue.response.id + "_" + selectedQue.response.invite_id +".mp4";
StorageFile storageFile = await transfersFolder.CreateFileAsync(videoFileName, CreationCollisionOption.ReplaceExisting);
// Open a file stream, ready to write video data
randomAccessStream = await storageFile.OpenAsync(FileAccessMode.ReadWrite);
// Video recording to the specified stream
await videoCapture.StartRecordingToStreamAsync(randomAccessStream);
isRecordingStarted = true;
//timer = "0:00";
tbTimer.Text = "0:00";
dt.Start();
}
catch (Exception ex)
{
(new WebServices()).catchExceptions(ex);
}
}
This worked for me in the past, it was just a barcode scanner app that I coded up to fulfill a functional requirement. I put the transform on the <VideoBrush>.
<Grid x:Name="ContentPanel" Margin="12,0,12,0">
<Canvas x:Name="cam_canvas" Width="480" Height="480">
<Canvas.Background>
<VideoBrush x:Name="cam_video_brush" Stretch="None">
<VideoBrush.RelativeTransform>
<CompositeTransform Rotation="90" CenterX="0.5" CenterY="0.5" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Canvas.Background>
</Canvas>
</Grid>
Finally i solved my problem after 24 hours of efforts with below solution.
The line of code that causing issue by rotating video was below.
videoCapture.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, videoCapture.SensorRotationInDegrees);
here videoCapture is object of AudioVideoCaptureDevice
While using front camera, we need to invert the rotation of cameraSensor.
So I've used the above same code (mentioned in question) with one tiny modification in this videoCapture.SetProperty line of code. the correct line of code is as below.
videoCapture.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, -(videoCapture.SensorRotationInDegrees));
I just inverted the videoCapture.SensorRotationInDegrees by adding one minus sign (-) before it.
Hope this helps all..

Saving image as StorageFile

I am trying to save an image selected with FileOpenPicker. I am lunching this event when an image is selected
async void photoChooserTask_Completed(object sender, PhotoResult e)
{
// get the file stream and file name
Stream photoStream = e.ChosenPhoto;
string fileName = Path.GetFileName(e.OriginalFileName);
// persist data into isolated storage
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream current = await file.OpenStreamForWriteAsync())
{
await photoStream.CopyToAsync(current);
}
}
But this code which will give me the lenght of the saved file return 0
var properties = await file.GetBasicPropertiesAsync();
i = properties.Size;
Have I done something wrong in saving the image?
You may need to flush the stream.
If that does not work, add a breakpoint and check the two streams' lengths after the copy. Are they equal? They should be. Anything suspicious on those two stream objects?
Edit
On the image you posted, I can see that you use the SetSource method of a BitmapImage with the same Stream that you copy. Once you do that, the Stream's Position will be at the end, as it was just read by that call.
CopyToAsync copies everything after the current Position of the Stream you call it on. Since the position is at the end, because it was just read, the CopyToAsync does not copy anthing.
All you need to do to fix your problem is set the stream's Position to 0.

printing html output to printer on a server application

I am writing a service on the local server side which will accept the printer name and other inputs from the UI application and print the html file to the desired network printer. it is not a desktop application. I have a processed html file which I am reading into a string and want its output sent to the desired printer.
1 way I could found is to create an image by reading it into a JEditorPane(though using a swing class is not great approach) and then saving an image which is then sent to the printer. But it fails when the html has an tag and that image is not renderred within the image created by html. Can someone help me with a method that can solve my problem. The printer is able to support postscripts as well.
This is my approach
protected void generateDoc(DataObj data) {
DocFlavor dsc =
DocFlavor.INPUT_STREAM.PNG;
// get the html file's contents
String receipt =
getFileContents("Receipt.html");
// process the html contents and insert the data details
receipt = processHTMLContents(receipt, data);
// create image of the receipt
createReceiptImage(receipt);
InputStream is =
null;
try {
is =
new FileInputStream(new File("testingToday.png")); // the same image which was created below
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// create the doc to be sent to the printer
Doc doc =
new SimpleDoc(is, dsc, null);
return doc;
}
/**
* Create an image of the html receipt.
* #param htmlReceipt processed html receipt
* #return
* #throws InterruptedException
*/
protected void createReceiptImage(String htmlReceipt) throws InterruptedException {
JEditorPane pane =
new JEditorPane();
//pane.setEditable(false);
pane.setEditorKit(new HTMLEditorKit());
pane.setContentType("text/html");
pane.setText(htmlReceipt);
pane.setSize(650, 850);
pane.setBackground(Color.white);
// Create a BufferedImage
BufferedImage image =
new BufferedImage(pane.getWidth(), pane.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g =
image.createGraphics();
// Have the image painted by SwingUtilities
JPanel container =
new JPanel();
SwingUtilities.paintComponent(g, pane, container, 0, 0, image
.getWidth(), image.getHeight());
g.dispose();
ImageIO.write(image, "PNG", new File("testingToday.png")); // this would be replaced by a relative network location
}
and this doc is then sent to the printer. but this is not a desirable approach as it is swing class and it is not able to render any images inside the html. I have already spent around a week over it but still cant end upon a solution. how to fix this or what can be the solution?
Although the question seems old, you can have a look at this question.. Basically it converts a HTML to PDF & then you print the PDF... hope this helps

How do I display a PDF onto a JSF page

I want to display a PDF file onto my JSF page, I have check this how to display a pdf document in jsf page in iFrame, but I dont want to display it on an iframe(since it will generate scroll bar). I just want to display the pdf onto a page like an image and able to give a width and height for it.
EDIT Hi BalusC. I still cant be able to display the pdf inline. Here is my code.
#WebServlet(name = "pdfHandler", urlPatterns = {"/pdfHandler/*"})
public class pdfHandler extends HttpServlet {
private static final int DEFAULT_BUFFER_SIZE = 10240;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestedFile = request.getPathInfo();
File file = new File("/Users/KingdomHeart/Downloads/Test/pdf/" + requestedFile);
response.reset();
response.setContentType("application/pdf");
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try{
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while((length = input.read(buffer)) > 0){
output.write(buffer, 0, length);
}
}finally{
output.close();
input.close();
}
}
...
}
It still prompt me to download the pdf file. The pdf file that get downloaded to my computer is the correct pdf file btw. Can u spot anything wrong?
There's not really another way (expect from HTML <object> tag which would have the same "problems"), but you can just give the <iframe> a fixed size and disable the scrolling as follows:
<iframe src="foo.pdf" width="600" height="400" scrolling="no"></iframe>
If you also want to hide the (default) border, add frameBorder="0" as well.
You should take a look at ICEpdf, it creates an image on the server side, gives zooming, and other controls (demo).
Try going into Adobe Reader, and under the Options dialog there are web settings where you can indicate that you always want PDF type documents to open within the browser.
This is unfortunately a client side fix and doesn't take into account other PDF readers.
What you want is impossible. Browsers are not magic, they just display different kinds of documents, some of which (HTML) can embed objects provided by plugins (flash, java) and other documents inside iframes (pdf, flash, html). If you want to show pdf miniatures, you will have to generate images on the server.