Situation
I am currently exploring android development on xamarin and therefor decided to develop a small game.
Within the game, I have an ImageButton to access some menus. For instance the level up screen.
I made some low res image for the image button:
Issue
Now, if I use this in the image button, the image gets scaled up and therefore looks Blurry:
I guess, the reason being is bi-linear image sizing.
The proper implementation for my specific case would be sizing with nearest neighbor, as it preserves the low pixel look:
Question
How would I go about changing this? I have found code for WPF winforms but realized that xamarin has different calls...
class ImageButtonWithHardEdgeExpansion : SomeControl
{
public InterpolationMode InterpolationMode { get; set; }
protected override void OnPaint(PaintEventArgs paintEventArgs)
{
paintEventArgs.Graphics.InterpolationMode = InterpolationMode;
base.OnPaint(paintEventArgs);
}
}
For an intermediate workaround, I can use an external image resizer and store the image in high res... but that defies the purpose for me a little. so I am looking for a more long term solution.
You can use the padding to do this.
Before padding:
After padding:
Related
I'm currently working on a new app, and I want to add customized animations to it (not talking about activity transitions).
To show you exactly what I mean, take a look at this video at 2:30-2:33:
https://www.youtube.com/watch?v=XBMdjX5bbvk&nohtml5=False
You see the chest jumping to the screen and opens smoothly with beautiful animation?
I'd really like to know how can it be added to an Android app, is it a frame animation?
I mean, I can make this animation, in 2D, I just want to know how to add it (I'm using Android Studio) without causing memory overflow.
Thanks!
For you question:
You see the chest jumping to the screen and opens smoothly with
beautiful animation? I'd really like to know how can it be added to an
Android app, is it a frame animation?
I don't think it is a frame animation. I guess this has been implemented using OpenGL. You can find the official tutorial here.
If you want to make simple 2d animations, you can use the AnimationDrawable api provided by android. You basically need frames for the sequence of animations and then you can create the animation using the following code:
// you would need an `ImageView` object as a placeholder for the animation
ImageView mMascotView = findViewById(...);
// prepare the animation object ..
AnimationDrawable mMascotAnimation = new AnimationDrawable();
final int frameTime = 250; // time in milliseconds
// adding the frames to the animation object. You can specify different
// times for each of these in milliseconds
mMascotAnimation.addFrame(getResources().getDrawable(R.drawable.frame1),frameTime);
mMascotAnimation.addFrame(getResources().getDrawable(R.drawable.frame2),frameTime);
mMascotAnimation.addFrame(getResources().getDrawable(R.drawable.frame3),frameTime);
// make it loop infinitely ..
mMascotAnimation.setOneShot(false);
// set the background of the `ImageView` as the `AnimationDrawable`object ..
mMascotView.setBackground(mMascotAnimation);
// start the animation ..
mMascotAnimation.start();
Note: You should not call the AnimationDrawable.start()inside the onCreate() method of the activity. The views are not ready yet. You should use the callback on onWindowFocusChanged() method and start the animation there:
#Override
public void onWindowFocusChanged (boolean hasFocus)
{
//Start animation here
if(hasFocus) {
mMascotAnimation.start();
}
}
In xcode, and tvos, the 3D parallax icons in the asset catalog are shown as image stacks. But this is not the case with the so called top shelf image.
Is it possible to convert the top shelf image to a multi layer image stack in xcode?
Only content that is focusable is multilayered and then you need to provide several of them.
There are 3 top shelf types, but unfortunately none of them fit your needs.
You can read more about them in apple tv human interface guide lines.
1) single, static top shelf image
Provide a visually rich static image. Your app’s static top shelf
image is used when dynamic content isn’t provided or is unavailable.
Use it as an opportunity to highlight your brand.
Don’t imply interactivity in a static image. The static top shelf
image isn’t focusable, so it shouldn't include elements that make it
appear interactive.
2) "Dynamic Content Layouts" - "Sectioned Content Row"
this is for content similar to portrait movie posters. those can be multilayered, but:
Provide enough content to constitute a complete row. At a minimum,
load enough images in a sectioned content row to span the full width
of the screen.
3) "Dynamic Content Layouts" - "Scrolling Inset Banner"
this is for content similat to wide screen advertising banners. those can be multilayered, but:
A minimum of three images is recommended for a scrolling banner to
feel effective.
To make Dynamic Content you need an Apple TV extension. To include a layered image in the content use the Apple Parallax Previewer app to load all the images in the layered image, and export as an LSR file. Drop the LSR into an Apple TV Extension target. Use the code below to create a scrolling inset (rather than a sectioned one as in the RW tutorial). Then read in the file from the app bundle.
Note that the Top Shelf will "scroll through" your images so you probably want 3 related layered images (as the above answer suggests). You can see what a single image looks like (pretty lame) in this video.
import Foundation
import TVServices
class ServiceProvider: NSObject, TVTopShelfProvider {
override init() {
super.init()
}
// MARK: - TVTopShelfProvider protocol
var topShelfStyle: TVTopShelfContentStyle {
// Return desired Top Shelf style.
return .inset
}
var topShelfItems: [TVContentItem] {
let v1Ident = TVContentIdentifier(identifier: "V1", container: nil)!
let v1Content = TVContentItem(contentIdentifier: v1Ident)!
v1Content.imageURL = Bundle.main.url(forResource: "v1", withExtension: ".lsr")
// Create an array of TVContentItems.
return [v1Content]
}
}
i am using the declarative/ui-binder method of adding images to a page. this is in combination with using the ImageBundle functions that GWT provides.
what i would like to do is change the image out when i hover over the image. my questions are: what are the best way to do this, and is my current method the best method in the first place?
my code looks something similar to:
<ui:with field='res' type='path.to.my.app.AppResources' />
...
<g:HorizontalPanel ui:field='horizPanel' >
<g:Image ui:field='image1' resource='{res.image1}'/>
</g:HorizontalPanel>
that is then tied into an ImageBundle class via the AbstractImagePrototype.
then, in my main handler, i have something like:
#UiHandler("image1")
public void onMouseOver(MouseOverEvent event)
{
/* What do I do here? */
}
say i want to replace image1 with image2 when the user hovers over image1 (and put image1 back when the pointer leaves the image). do i replace the image1 object? do i use the setUrl function for that image? do i create a whole new image, and use the add/remove functions for the horizontal panel to add it on? that seems awfully inefficient. do i not even need an ImageBundle; can i add images via something like <g:Image .... url='path/to/image1.png' /> and then use CSS and the hover attribute to swap out the image?
some guidance would be great. the GWT documentation is seriously lacking in this area. thanks.
PushButton is good for this kind of behavior. You can go father than :hover - you can specify arbitrary html and widgets for different faces of the buttons.
See gwt pushButton in UiBinder for an example in uibinder.
There will be more overhead in this approach, since it does register mouse handlers and set up a whole widget - if you really only need the rollover image and not any other event handling, a :hover css selector (maybe with a #sprite?) is probably best.
Using mouse handlers here seems a little overhead. I would use css and the hover selector
.foo {
background: url('path/to/image1.png');
/* height, width, etc. */
}
.foo:hover {
background: url('path/to/image2.png');
/* ... */
}
then use a widget that renders a div element (e.g. SimplePanel) instead of an image and set the style foo as stylePrimaryName
<g:HorizontalPanel ui:field='horizPanel' >
<g:SimplePanel ui:field='image1' stylePrimaryName='foo'/>
</g:HorizontalPanel>
I recently asked a question about translucent components causing odd artifacts from seemingly not updating properly. The answer I received caused the artifacts to go away, but at the cost of translucency.
The solution was to- for every translucent component- also call the setOpaque(false) function. This way, Swing knew that it needed to redraw the background behind those components.
However, this came at the cost of the translucency that I was trying to achieve. It caused the components to become transparent instead.
The premise is this: I am designing the GUI for a chat client, and a feature request was to have a background. I successfully got the background working by following a code snippet for extending the JPanel class, but then I wanted the components to allow the background to show. After setting their translucency, remnants of updated components were being displayed where they shouldn't have been. I came here and got my problem solved, but now I've got a new problem. So here we are.
So, here is what I've surmised:
-Calling the setOpaque(false) function for each desired component and NOT setting a translucent color does not achieve what I want.
-Setting a translucent color and NOT calling setOpaque(false) allows the translucent background to show, but causes artifacts, putting me back at square one.
So I need some middle ground between transparent with no artifacts, and translucent with artifacts. Namely, I want a translucent background (not completely transparent) that has no artifacts.
It seems like I'm going to need to override the JFrame to cause it to repaint all its components, regardless of the opacity. Unless there's something I'm missing.. which is why I'm here!
Thanks!
(Here's a link to the original question, with a picture for reference: Java Swing - Translucent Components causing Artifacts)
One option would be to override the components and draw the background yourself:
class TranslucentLabel extends JLabel {
public TranslucentLabel(String text) {
super(text);
setOpaque(false);
}
#Override
public void paintComponent(Graphics g) {
g.setColor(new Color(255, 0, 0, 64));
Insets insets = getInsets();
g.fillRect(insets.left, insets.top,
getWidth() - insets.left - insets.right,
getHeight() - insets.top - insets.bottom);
super.paintComponent(g);
}
}
EDIT: Alternatively you could draw the translucent background colour for the child components directly onto the panel, then you would not have to override components:
class YourPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g.create();
// Draw your background image here to g2d.
g2d.setColor(new Color(255, 0, 0, 64));
Area area = new Area();
for (Component component : getComponents()) {
area.add(new Area(component.getBounds()));
}
g2d.fill(area);
g2d.dispose();
}
}
There is a disadvantage to this approach. If there is a genuinely transparent part of a component (such as a rounded border), then its entire background will be coloured.
I have a very simple application that has one screen and one button. The main screen has a verticalFieldManager with a BitmapField inside it, and one button beneath the bitmap. I want to be able to overlay another image on top of this when the user clicks a button. The overlay image is a PNG with transparent background, and this is important for design, so I can't use popupscreen or a new screen because the backgrounds are always white by default, and I've heard alpha doesn't really do the trick.
I guess what I'm asking is if anyone knows a simple way to...
A) take a standard verticalFieldManager and overlay a PNG on top of the inner contents
B) overlay a PNG over the screen, no matter the contents
The basic functionality of this app was intended to be - show an image. on click, show another overlaid on top. on click again, remove the popup image.
I haven't found anything that addresses something like this online, but I have read of people doing similar things that utilize popupscreen and new screens in a way I don't need to do.
Hopefully this makes sense.
Thanks
Have you tried something like this in your custom class that overrides a screen?
EncodedImage _overlayImage;
boolean _overlay = false;
// this is to catch the click, you might do it different
public void fieldChanged(Field field, int context)
{
if (field == _imgChangeButton) {
// get the overlay image here, however you want
_overlayImage = getEncodedImageResource(blah);
_overlay = true;
invalidate();
}
}
protected void paint(Graphics graphics) {
super.paint(graphics);
if (_overlay) {
graphics.drawImage(...);
}
}
If the PNG has transparency in it the bb drawImage stuff should deal with it ok. In the drawImage call obviously you can mess around with finding the existing image and setting the x,y right on top of it.
In general I would say do a lot of testing with paint() and messing with the graphics directly before you try to do anything with another screen. You can do a lot overriding paint() for the screen... you get the whole graphics.