Transparent parts in Skia View - xamarin

I'm trying to use SkiaSharp in Xamarin.forms to draw some polygons on top of an image.
The image is downloaded from a server and than cached in background. So I would prefer not to manipulate the image itself and instead draw a new canvas and place it in a new view on top of the image, like in the screenshots. (using relative layout)
As you can also see in the screenshots, placing the rectangular is not the problem but the "transparent" part is not really transparent.
Code of the first screenshot:
using (var paint = new SKPaint ()) {
paint.IsAntialias = true;
using (var path = new SKPath ()) {
path.MoveTo (0f, 0f);
path.LineTo (width, height);
path.LineTo (0, width);
path.Close ();
paint.Color = SKColors.Orange;
canvas.DrawPath (path, paint);
}
}
In the second I tried to use
canvas.Clear(SKColors.Transparent);
but it only changes to the black background.
Does anyone know whether it is possible to have completely transparent parts in a skia view?

Your question helped me solve this today:
As well as setting the canvas' colour as transparent, the containing Xamarin Forms element needs to be transparent too!
C#
canvas.Clear(SKColors.Transparent);
XAML
<views:SKCanvasView ... BackgroundColor="Transparent" />

guessing here cause you forgot the screenshots,
what you probably want to do is using clipping
something like :
canvas.Clear();
canvas.ClipPath(path);
canvas.ResetMatrix();
canvas.DrawBitmap(...)

Related

How to fit image to center while using TouchImageView?

I have a gallery application that needs to zoom and pan. Instead of using default imageview , I found a sample touchmageview on internet and copied it. I called my images with TouchImageView and now i can zoom and pan the images that I called from my drawable folder. Then I added gallery to my project. Now the problem is that I can not fit the images to the screen.When I use scaletype.center then it fits the image to the screen but now zoom and pan features are not working. This is my gallerylistener ;
gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(Display.this, "Your selected position = " + position, Toast.LENGTH_SHORT).show();
// show the selected Image
img.setScaleType(ScaleType.CENTER_INSIDE);
img.setImageResource(Imgid[position]);
}
});
As you see , if I add img.setScaleType(ScaleType.CENTER_INSIDE); then the TouchImageView class doesn't work and I am not able to zoom and pinch and pan etc.. It only display the image. When I delete this code , then I can zoom but then when I change the picture to another one , the new one has the previous image's size. But I want to fit them to the center. Is there any way to reset the scaletype before calling the new image ?
By the way I have only one imageview in xml.
There is a similar question on this link but the solution did not work for me.
how to get setScaleType(ImageView.ScaleType.FIT_CENTER) effect using setScaleType(ImageView.ScaleType.MATRIX)

Is there a way of finding out what would my orientation have been?

I'm currently writing a portrait only app, but I have a customer requirement that they'd like to implement a special feature if the phone is turned on its side.
To be clear they don't want the page to change orientation - so keeping the page as portrait works well here - but they do want to be able to detect the sideways change.
Is there anyway of finding this out (e.g. from rootframe or from some other object?) or do I have to access the Accelerometer data and work it out myself?
To be clear on this...
I'm trying to keep the page in portrait at all times.
and if I specify SupportedOrientations="portraitorlandscape" then keeping the page in portrait seems to be hard (correct me if I'm wrong, but it just doesn't seem to want to stay in portrait - the MS SDK is too good at making the page go landscape)
and if I don't specify SupportedOrientations="portraitorlandscape" then I don't get calls to OnOrientationChanged in either the page or the RootFrame
And as the icing on the cake... I need the phone to stay in portrait mode too - I need the SystemTray to stay at the top of the screen (the portrait top).
You can handle the OnOrientationChanged event which will return a PageOrientation enumeration.
Accepting this because of the comments:
#Stuart - You may find the Orientation Helper class in this starter kit useful. It uses the accelerometer, so I guess you'll have to use that, but it might save you time rolling out your own version: http://msdn.microsoft.com/en-us/library/gg442298%28VS.92%29.aspx#Customizing_Behavior
This might help, but for a case when arriving to this particular page, not for the initial page - so only partly answering the question. It trigs the OnOrientationChanged although no change has been done! (Figured out this solution after having tried to find a solution for two days) :
On the particular page, write in . xaml code
Orientation="None"
On the .xaml.cs side, write under
InitializeComponent();
Orientation = this.Orientation;
this.OrientationChanged += new EventHandler<OrientationChangedEventArgs>
(OnOrientationChanged);
and separately
void OnOrientationChanged(object sender, OrientationChangedEventArgs e)
{
if ((e.Orientation & PageOrientation.Landscape) != 0)
{
MyImage.Height = 480; //for example
}
{
MyImage.Width = 480; // for example
}
}
In my case, I placed the image as follows:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel>
<Image x:Name="MyImage"/>
</StackPanel>
.. followed by other code, still loading during which time picture is shown ...
This decreases the size of the image when in Landscape mode when entering the page!
Got the solution, finally, after having seen Jeff Prosises site
Detect orientation change:
http://alan.beech.me.uk/2011/04/19/detecting-orientation-change-wp7dev/
I had to do a similar thing in one of my apps before where an image that is used as the background doesnt rotate but other items on the page do.
The code looks a bit like this:
protected override void OnOrientationChanged(OrientationChangedEventArgs e)
{
// Keep the image in the same position as in portrait
// But still allows other controls to rotate when orientation changes.
switch (e.Orientation)
{
case PageOrientation.LandscapeRight:
ForegroundImage.RenderTransform = new CompositeTransform { Rotation = 90 };
ForegroundImage.RenderTransformOrigin = new Point(0.5, 0.5);
ForegroundImage.Margin = new Thickness(158.592, -158.792, 158.592, -160.558);
break;
case PageOrientation.LandscapeLeft:
ForegroundImage.RenderTransform = new CompositeTransform { Rotation = 270 };
ForegroundImage.RenderTransformOrigin = new Point(0.5, 0.5);
ForegroundImage.Margin = new Thickness(158.592, -158.792, 158.592, -160.558);
break;
default: // case PageOrientation.PortraitUp:
ForegroundImage.RenderTransform = null;
ForegroundImage.RenderTransformOrigin = new Point(0, 0);
ForegroundImage.Margin = new Thickness();
break;
}
base.OnOrientationChanged(e);
}
Unfortunately there's no real work around for the system tray or app bar. For the system tray you could hide this though and then only show it (for a period of time) when the user taps or swipes near that part of the screen.

Getting JPanel's Image

I'm having problems creating a BufferedImage from an offscreen JPanel. Specifically, I'm trying a draw the image of a JPanel (which contains some Java3D elements) as a background image for an application I'm working on.
I've found several threads describing how to do get a JPanel's Image by painting the JPanel to a BufferedImage's graphics context, but when I draw the BufferedImage, all I get is a big white rectangle.
Here's my code:
SimpleWorld j3DPanel; // a custom JPanel that contains some simple Java3D elements
// CONSTRUCTOR
public GameBackgroundObject()
{
super();
// Here I set up a JPanel that contains some Java3D elements.
j3DPanel = new SimpleWorld();
j3DPanel.setSize(mainLevel.SCREENW, mainLevel.SCREENH);
j3DPanel.setBounds(0,0,mainLevel.SCREENW, mainLevel.SCREENH);
j3DPanel.doLayout();
j3DPanel.validate();
}
protected void draw(Graphics2D parentComponentGraphics, ...)
{
super.draw(parentComponentGraphics, ...);
int w = j3DPanel.getWidth();
int h = j3DPanel.getHeight();
BufferedImage j3DImg = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = j3DImg.createGraphics();
j3DPanel.paint(g);
parentComponentGraphics.drawImage(j3DImg, null, null);
}
Also, I've tried adding my JPanel to the contents of a JFrame. It works there and shows the rendered Java3D elements correctly. However, I just get this big white rectangle whenever I try to get the BufferedImage of the JPanel and draw that image.
Drawing a Java 3D scene probably fails because its Canvas3D component is heavyweight. Using the lightweight panel 'com.sun.j3d.exp.swing.JCanvas3D' might solve this problem. Its use is a bit tricky. See the corresponding Java 3D sample 'JCanvas3DExample' or try one of the derived works from here http://www.interactivemesh.org/testspace/j3dmeetsswing.html#leightweight
Try calling:
j3DPanel.paintComponent(g);
instead of:
j3DPanel.paint(g);

Image gets clipped while changing orientation using Qt

HI all,
I wnt to develop an ImageViewer using qt. I m trying to resize big images by scaling them. My problem is , when i change the screen orientation some part of the image gets clipped and also if i open the image in landscape mode, by default the size of image remains small even when i change back to portrait mode. What am i Doin wrong?
Please help me out. Heres the code dat i hv written
ImageViewer::ImageViewer()
{
setAttribute(Qt::WA_DeleteOnClose);
QAction *back = new QAction(this);
back->setText(QString("Back"));
connect(back,SIGNAL(triggered()),this,SLOT(close()));
back->setSoftKeyRole(QAction::PositiveSoftKey);
addAction(back);
imageLabel = new QLabel();
imageLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
imageLabel->setAlignment(/*Qt::AlignLeft|*/Qt::AlignCenter);
QWidget *widget = new QWidget;
layout=new QStackedLayout();
layout->addWidget(imageLabel);
widget->setLayout(layout);
setCentralWidget(widget);
}
void ImageViewer::showImage(QString filePath)
{
QImageReader reader;
reader.setFileName(filePath);
QSize imageSize = reader.size();
imageSize.scale(size(), Qt::KeepAspectRatio);
reader.setScaledSize(imageSize);
QImage image = reader.read();
imageLabel->setPixmap(QPixmap::fromImage(image));
imageLabel->adjustSize();
}
You should re-implement QLabel's resizeEvent or install event filter to it and handle QResizeEvent there
The content of showImage method should go to handler of a resize event.
Currently you are using size() of ImageViewer widget (which seems to be derived from QMainWindow), it's better to use imageLabel.size(); or the best QResizeEvent::size() as this will prevent a problem if you will change UI layout in future.

WP7 transition between Canvas's in a Grid

I have two canvas's in a Grid, full scene "images" that I want to transition, I wonder how I would go about transitioning between these two Canvas controls.
Programatically I add the first canvas to the grid, then I add the second canvas to the grid, and remove the first, what I really want to do is transition between them.
Any suggestions on how I might achieve this programatically?
Thanks.
Edit: I have implemented this method, but am having problems, anyone able to tell me if I'm using it wrong?
private void doTransitionIn(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeIn;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
private void doTransitionOut(Canvas slide)
{
SlideTransition slideLeft = new SlideTransition();
slideLeft.Mode = SlideTransitionMode.SlideDownFadeOut;
ITransition transition = slideLeft.GetTransition(slide);
transition.Completed += delegate { transition.Stop(); }; transition.Begin();
}
And here is how I use it:
SceneGrid.Children.Add(nextCanvas);
doTransitionIn(nextCanvas);
doTransitionOut(currentCanvas);
SceneGrid.Children.Remove(currentCanvas);
The problem with this is that the animation only seems to start from part way down the screen, as in, i only see it slide the last 20 or so pixels, it doesn't slide all the way.
Depending on what you mean by "transition" I'd look at creating a StoryBoard to animate the hiding/showing of each canvas.
I would recommend using the TransitioningContentControl which is part of the Silverlight Toolkit. To use this control, make your first Canvas the Content of this control. To transition, simply change the Content to your next Canvas and the TransitioningContentControl does the rest!
There are a number of blog posts that provide tutorials for this control:
http://blogs.academicclub.org/uidev/2010/06/12/transitioning-content-in-silverlight/

Resources