I am trying to draw some txt using method as in the PlayN Showcase app:
protected static Layer createTextLayer(TextLayout layout, int color) {
CanvasImage image = graphics().createImage((int) Math.ceil(layout.width()), (int) Math.ceil(layout.height()));
image.canvas().setFillColor(color);
image.canvas().fillText(layout, 0, 0);
return graphics().createImageLayer(image);
}
It works fine for HTML/Canvas but not for HTML/Dom.
Try to use tripleplay (https://github.com/threerings/tripleplay). Maybe it will help.
Label label = new Label("MY LABEL");
Interface iface = new Interface();
Stylesheet rootSheet = Stylesheet.builder().create();
Root nameroot = iface.createRoot(AxisLayout.horizontal().gap(300), rootSheet);
nameroot.add(label);
nameroot.setSize(100, 30);
nameroot.setStyles(Styles.make(Style.HALIGN.left));
PlayN.graphics().rootLayer().add(nameroot.layer);
Related
I need to do that in my program. I have to do it in two ways:
1.) by my own, with the following code:`
private Image convertToGrayScale(Image image) {
WritableImage result = new WritableImage((int) image.getWidth(), (int)
image.getHeight());
PixelReader preader = image.getPixelReader();
PixelWriter pwriter = result.getPixelWriter();
for (int i = 0; i < result.getWidth(); i++) {
for (int j = 0; j < result.getHeight(); j++) {
Color c = preader.getColor(i, j);
double red = (c.getRed() * 0.299);
double green = (c.getGreen() * 0.587);
double blue = (c.getBlue() * 0.114);
double sum = c.getRed() + c.getBlue() + c.getGreen();
pwriter.setColor(i , j, new Color(sum, sum, sum, 1.0));
}
}
return result;
}
2.) with the help of the openCV library, with the following code (it was copied almost perfectly from their site) :
public WritableImage loadAndConvert() throws Exception {
//Loading the OpenCV core library
System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
String input = "C:/Users/Dan Ivgy/eclipse-workspace/LuckyBride/sample/20180402_170204.jpg";
//Reading the image
Mat src = Imgcodecs.imread(input);
//Creating the empty destination matrix
Mat dst = new Mat();
//Converting the image to gray scale and saving it in the dst matrix
Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGB2GRAY);
// Imgcodecs.imwrite("C:/opencv/GeeksforGeeks.jpg", dst);
//Extracting data from the transformed image (dst)
byte[] data1 = new byte[dst.rows() * dst.cols() * (int)(dst.elemSize())];
dst.get(0, 0, data1);
//Creating Buffered image using the data
BufferedImage bufImage = new BufferedImage(dst.cols(),dst.rows(),
BufferedImage.TYPE_BYTE_GRAY);
//Setting the data elements to the image
bufImage.getRaster().setDataElements(0, 0, dst.cols(), dst.rows(), data1);
//Creating a WritableImage
WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
System.out.println("Converted to Grayscale");
return writableImage;
}
In both cases, the problem was that i have'nt got a "greyscale" output, just somthing different (and before you
asked: yeas, i have tried to to do it on several pictures, not only one)
Here's the input picture and the output picture:
Well, as you can see, this is Not a greyscale! maybe a sunset-scale..
I'd really appraciate any help, Thank you :)
(espcially if there's something faster out there since those solutions rather takes a while to run)
If someone knows, why there is not some built in option in javaFX as there is a lot of sophisticated imageview effects and this one is so simple and so prevalent.
UPDATE:
i found a website that do somthing similar to ehat i did - and somehow i got a different output! i don't get it
here's the website.
and here's the output from my computer:
my output
UPDATE#2: as #matt correctly asked, here's the code that use this method:
ImageIO.write(SwingFXUtils
.fromFXImage
(convertToGrayScale(new Image(getClass().getResource("1_CNc4RxV85YgthtvZh2xO5Q.jpeg").toExternalForm()) ), null), "jpg", file);
the original target was to show the image to rhe user, and the problem was there, so i changed the code to this one which save the image so i could isolate the problem more easly..
Ok guys, after some research, and endless number of attememts i got what i need
to solve the problem ill show my solution here and come to a coclude of my insights about this issue..
first, ill give the the disticntion between "SAVING the file" and "Setting the file in the ImageView.
when we want just to show it in image view, i have'ne expereinced any problem using almost every solution suggested here. the most simple, short and sweet (in my opinion) is the following one:
private Image convertToGrayScale(Image image) {
WritableImage result = new WritableImage((int) image.getWidth(), (int) image.getHeight());
PixelReader preader = image.getPixelReader();
PixelWriter pwriter = result.getPixelWriter();
for (int i = 0; i < result.getWidth(); i++)
for (int j = 0; j < result.getHeight(); j++)
pwriter.setColor(i , j, preader.getColor(i, j).grayscale());
return result;
}
(for convinience, i ignored exception handling)
it works fine when i use it along when i use it along with the following code:
Image img1 = convertToGrayScale(new Image(filepath);
imageView.setImage(img1);
about SAVING this output image, after some research and using #trashgold 's references, and this important one :
i got my solution as the following:
private void saveBadImage(BufferedImage originalImage, File dest) throws IOException
{
// use the following line if you want the first parameter to be a filepath to src image instead of Image itself
//BufferedImage originalImage = ImageIO.read(file);
// jpg needs BufferedImage.TYPE_INT_RGB
// png needs BufferedImage.TYPE_INT_ARGB
// create a blank, RGB, same width and height
BufferedImage newBufferedImage = new BufferedImage(
originalImage.getWidth(),
originalImage.getHeight(),
BufferedImage.TYPE_INT_RGB);
// draw a white background and puts the originalImage on it.
newBufferedImage.createGraphics().drawImage(originalImage,0,0,null);
// save an image
ImageIO.write(newBufferedImage, "jpg", dest);
}
and, i use it with the following code:
Image img1 = convertToGrayScale(new Image(filepath));
BufferedImage img2 = new BufferedImage((int) img1.getWidth(), (int) img1.getHeight(), BufferedImage.TYPE_INT_ARGB);
saveBadImage(img2, file);
and, it works perfectly!
Thank you all guys, and i hope my insights will help to some people
I decided to work in awt, then create a javafx image.
public class App extends Application {
#Override
public void start(Stage stage) {
WritableImage gray = null;
try {
BufferedImage awtImage = ImageIO.read(new URL("https://i.stack.imgur.com/ysIrl.jpg"));
gray = new WritableImage(awtImage.getWidth(), awtImage.getHeight());
BufferedImage img2 = new BufferedImage(awtImage.getWidth(), awtImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
for(int i = 0; i<awtImage.getWidth(); i++){
for(int j = 0; j<awtImage.getHeight(); j++){
int c = awtImage.getRGB(i, j);
int r = (c>>16)&255;
int g = (c>>8)&255;
int b = (c)&255;
int s = (int)(r*0.299 + g*0.587 + b*0.114);
int gr = (255<<24) + (s<<16) + (s<<8) + s;
img2.setRGB(i, j, gr);
}
}
gray = SwingFXUtils.toFXImage(img2, gray);
} catch (IOException e) {
e.printStackTrace();
}
ImageView view = new ImageView(gray);
ScrollPane pane = new ScrollPane(view);
Scene scene = new Scene(new StackPane(pane), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Both methods work for me, so I'm not sure if this helps you. I can save the result too.
System.out.println("saving " +
ImageIO.write(img2, "PNG", new File("tested.png")) );
If you're using oracles jdk, I think you can save JPEG. I am using OpenJDK which doesn't seem to be able to write JPEG.
This is fairly straight forward, but I have some custom ShellRenderers for my App in Xamarin Forms, and I'm having issues with the scaling of images. In particular, Android looks fantastic with the more pixel-dense image (800x200). It looks great on every screen.
The renderer just ensures that the top of the screen is made of the "theme" color, and is presented in the center of the it. It's that simple/straight-forward.
On iOS, it looks awful and blurred. I'm not sure if there's something I need to set or update (or maybe a different graphics stack?) to make it render with higher pixel density... See my attached renderer:
public class CustomShellRenderer : ShellRenderer
{
#region Methods
protected override IShellSectionRenderer CreateShellSectionRenderer(ShellSection shellSection)
{
var renderer = base.CreateShellSectionRenderer(shellSection);
if (renderer != null)
{
var navigationBar = (renderer as ShellSectionRenderer).NavigationBar;
if (navigationBar != null)
{
navigationBar.BarTintColor = Colors.LightColor.ToUIColor(); //static colors
navigationBar.TintColor = Colors.LightColor.ToUIColor();
using (var logo = UIImage.FromResource(typeof(Images).Assembly, "Path.To.Logo.png"))
{
var statusFrame = UIApplication.SharedApplication.StatusBarFrame;
var navigationFrame = navigationBar.Frame;
var width = Math.Max(navigationFrame.Width, statusFrame.Width);
var fullArea = new CGRect(0, 0, width, navigationFrame.Height + statusFrame.Height);
UIGraphics.BeginImageContext(fullArea.Size);
var backgroundColor = Colors.PrimaryColor.ToUIColor();
backgroundColor.SetFill();
UIGraphics.RectFill(fullArea);
var logoArea = new CGRect(width * .35, statusFrame.Height, width * .3, navigationFrame.Height);
logo.Draw(logoArea);
var backgroundImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
(renderer as ShellSectionRenderer).NavigationBar.SetBackgroundImage(backgroundImage, UIBarMetrics.Default);
backgroundImage.Dispose();
}
}
}
return renderer;
}
#endregion
}
Any thoughts? Right now, the problem is that when it renders, there is an 800x200 image trying to squeeze into... 140x30 or so space on some emulators...
Thank you!
I am trying to resize a SystemIcon for use within a ErrorProvider.
Dim WarnProvider As New ErrorProvider
WarnProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink
WarnProvider.Icon = SystemIcons.Information.Clone()
WarnProvider.Icon.Size = New Size(16,16)
But the SystemIcons has the size set as a read only property.
Been messing with it for the past hour and have not found any good methods to make this work.
Can someone help?
Thanks
I was looking for the a method to do this as well, and came across this post. Here's what I ended up doing to resolve the issue.
I created a global static method to resize an icon.
public static class Global
{
public static Icon ResizeIcon( Icon icon, Size size )
{
Bitmap bitmap = new Bitmap(size.Width,size.Height);
using( Graphics g = Graphics.FromImage(bitmap) )
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(icon.ToBitmap(), new Rectangle(Point.Empty,size));
}
return Icon.FromHandle(bitmap.GetHicon());
}
}
Then I applied the icon in the constructor of the form after InitializeComponent() was called.
public SpecificationsDialog( int pid )
{
InitializeComponent();
warningProvider1.Icon = Global.ResizeIcon(SystemIcons.Warning,SystemInformation.SmallIconSize);
}
I was looking for the same thing and found the answer elsewhere, so I'll post here
http://www.codeproject.com/Questions/242780/error-provider-problem
WarnProvider.Icon = new Icon (SystemIcons.Warning, 16, 16);
or
WarnProvider.Icon = new Icon (WarnProvider.Icon, 16, 16);
I changed Drew's solution a little to be an extension method for the errorprovider:
public static ErrorProvider SetIcon(this ErrorProvider errorProvider, Icon icon, Size size)
{
Bitmap bitmap = new Bitmap(size.Width, size.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(icon.ToBitmap(), new Rectangle(Point.Empty, size));
}
errorProvider.Icon = Icon.FromHandle(bitmap.GetHicon());
return errorProvider;
}
Then it's can be used like so:
ErrorProvider ep = new ErrorProvider();
ep.SetIcon(SystemIcons.Asterisk, new Size(16,16));
I'm using the tooltipManager as described HERE.
I want to display a custom tooltip for the buttons of a buttonbar.
The buttonbar's declaration is as follow:
<mx:ButtonBar id="topToolbar" height="30" dataProvider="{topToolbarProvider}"
iconField="icon" itemClick="topToolbarHandler(event)"
buttonStyleName="topButtonBarButtonStyle"
toolTipField="tooltip"/>
Until here, everything works fine. I do see the proper text displaying in a tooltip.
Then, I created a custom tooltip manager using the tutorial quoted previously:
public class TooltipsManager
{
private var _customToolTip:ToolTip;
public function TooltipsManager()
{
}
public function showToolTipRight(evt:MouseEvent, text:String):void
{
var pt:Point = new Point(evt.currentTarget.x, evt.currentTarget.y);
// Convert the targets 'local' coordinates to 'global' -- this fixes the
// tooltips positioning within containers.
pt = evt.currentTarget.parent.contentToGlobal(pt);
customToolTip = ToolTipManager.createToolTip(text, pt.x, pt.y, "errorTipRight") as ToolTip;
customToolTip.setStyle("borderColor", "0xababab");
// Move the tooltip to the right of the target
var xOffset:int = evt.currentTarget.width + 5;//(customToolTip.width - evt.currentTarget.width) / 2;
customToolTip.x += xOffset;
}
public function showToolTipAbove(evt:MouseEvent, text:String):void
{
var pt:Point = new Point(evt.currentTarget.x, evt.currentTarget.y);
// Convert the targets 'local' coordinates to 'global' -- this fixes the
// tooltips positioning within containers.
pt = evt.currentTarget.parent.contentToGlobal(pt);
customToolTip = ToolTipManager.createToolTip(text, pt.x, pt.y, "errorTipAbove") as ToolTip;
customToolTip.setStyle("borderColor", "#ababab");
// Move tooltip below target and add some padding
var yOffset:int = customToolTip.height + 5;
customToolTip.y -= yOffset;
}
public function showToolTipBelow(evt:MouseEvent, text:String):void
{
var pt:Point = new Point(evt.currentTarget.x, evt.currentTarget.y);
// Convert the targets 'local' coordinates to 'global' -- this fixes the
// tooltips positioning within containers.
pt = evt.currentTarget.parent.contentToGlobal(pt);
customToolTip = ToolTipManager.createToolTip(text, pt.x, pt.y, "errorTipBelow") as ToolTip;
customToolTip.setStyle("borderColor", "ababab");
// Move tooltip below the target
var yOffset:int = evt.currentTarget.height + 5;
customToolTip.y += yOffset;
}
// Remove the tooltip
public function killToolTip():void
{
ToolTipManager.destroyToolTip(customToolTip);
}
[Bindable]
public function get customTooltip():ToolTip { return _customToolTip; }
public function set customTooltip(t:ToolTip):void { _customToolTip = t; }
}
Now, this is where I start having issues...
I'm trying to get to use this custom tooltip, but I don't know how to get the buttonbar to take it into account.
I created a function to see when could I call the functions in my TooltipsManager:
public function showTopToolbarTooltip(e:ToolTipEvent):void{
trace('blabla');
}
But it would seem that it's never taken into account. I've put this function in different buttonbar's events: tooltipcreate, tooltipstart, tooltipend but nothing happens. Not a single trace...
Could anyone tell me where to call the function of my tooltipManager?
Thanks a lot for your help.
Kind regards,
BS_C3
Actually, skipped a part of the tutorial =_= Attaching the functions to the mouseover/out events... Sorry for that.
I am creating a little map app where you are given information, video and images regarding different campuses in a university.
I am using the customContent method to insert video player object into the infoWindow but when I do this it gets rid of my text content and becomes the only visible thing to the user.
How Can I work around this and have both text and video in the infoWindow?
Demo link
public function createMarker(latlng:LatLng, name:String, address:String, video:String):Marker
{
var marker:Marker=new Marker(latlng);
marker.addEventListener(MapMouseEvent.CLICK, function(e:MapMouseEvent):void
{
//marker.openInfoWindow(new InfoWindowOptions({contentHTML:html + moulVid}));
var infoWindow:InfoWindowOptions = new InfoWindowOptions();
infoWindow.title = name;
var videoPlayer:VideoPlayer = new VideoPlayer();
videoPlayer.source = '../assets/video/' + video.toLocaleLowerCase();
videoPlayer.autoPlay = false;
videoPlayer.alpha = 0.8;
titleFormat = new TextFormat();
titleFormat.font = "Arial";
titleFormat.size = 14;
titleFormat.bold = true;
contentFormat = new TextFormat();
contentFormat.font = "Arial";
contentFormat.size = 12;
infoWindow.drawDefaultFrame = true;
infoWindow.titleFormat = titleFormat;
if (video != "") {
infoWindow.customContent = videoPlayer;
infoWindow.height = 300;
}
infoWindow.width = 380;
infoWindow.content = address;
infoWindow.contentFormat = contentFormat;
infoWindow.padding = 10;
marker.openInfoWindow(infoWindow);
});
You need to create a new object, called it like VideoAndTextInfoWindow, make it extend DisplayObject. Now in that component's constructor create and add a VideoPlayer and a TextField. This component may just publicly expose a videoSource and a text property. Create setters for those properties so that they set the correct properties on the VideoPlayer and TextField instances. Now set the infoWindow.customContent to a new instance of your VideoAndTextInfoWindow component.