Drawing in Canvas with GWT - gwt

I have two images that i want to draw into a canvas object. I got those images from a server and when the loadHandler invokes, i get the dimensions of the image (they have the same width and height) and calculate the dimensions of the canvas. Then i draw each image, at the calculated x,y position in canvas. The problem is that only one image appears in canvas. Why?
Here is a part of the code:
final Image siImg = new Image();
siImg.setVisible(false);
siImg.setUrl(Constants.URL_PREFIX + siPath);
siImg.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
int siWidth = siImg.getWidth();
int siHeight = siImg.getHeight();
siImg.removeFromParent();
if (!CategoryTableView.this.dimFromBg) {
CategoryTableView.this.width = siWidth;
CategoryTableView.this.height = siHeight * sSize;
//CategoryTableView.this.setPixelSize(CategoryTableView.this.width, CategoryTableView.this.height);
CategoryTableView.this.canvas.setPixelSize(CategoryTableView.this.width, CategoryTableView.this.height);
CategoryTableView.this.canvas.setCoordinateSpaceHeight(CategoryTableView.this.height);
CategoryTableView.this.canvas.setCoordinateSpaceWidth(CategoryTableView.this.width);
CategoryTableView.this.dimFromBg = true;
}
ImageElement imageElement = (ImageElement) siImg.getElement().cast();
int left = xOff;
int top = yOff + (siHeight * fi);
CategoryTableView.this.context.drawImage(imageElement, left, top);
}
});
RootPanel.get().add(siImg);
Ok i think i find it...i have to save the context's state each time. Is that right? (Because it works now!)

You add the image to your root panel in the last line
final Image siImg = new Image();
...
RootPanel.get().add(siImg);
instead of adding your canvas. So you will only see the image instead of the canvas. You have to add the Canvas to your root panel and draw both images to your canvas. For performance-reasons it is better to draw to a backbuffer instead of drawing directly to the canvas. Here is a little example:
Canvas canvas = Canvas.createIfSupported();
Canvas backBuffer = Canvas.createIfSupported();
Context2d context = canvas.getContext2d();
Context2d backBufferContext = backBuffer.getContext2d();
Image image1 = new Image("http://your.url.to/image.jpg");
image1.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
// do anything you want here
doDraw();
}
});
Image image2 = new Image("http://your.url.to/image2.jpg");
image2.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
// do anything you want here
doDraw();
}
});
RootPanel.get().add(canvas);
And the draw-method would look like this:
public void doDraw() {
backBufferContext.setFillStyle(redrawColor);
backBufferContext.fillRect(0, 0, width, height);
ImageElement imageElement = ImageElement.as(image1.getElement());
backBufferContext.drawImage(imageElement, 0, 0, 1024, 768, 0, 0, 102, 76);
ImageElement imageElement = ImageElement.as(image2.getElement());
backBufferContext.drawImage(imageElement, 0, 0, 1024, 768, 102, 76, 102, 76);
context.drawImage(backBufferContext.getCanvas(), 0, 0);
}
Please note: You have to use global variables in this example. Change this to your needs by either passing the arguments/classes or defining the variables class-wide. Also the drawing-areas are hardcoded in this example: this you have also to change to your needs.

Related

Unity: Reduce size of Render Texture before executing Texture2D.ReadPixels

I'm working on a code where I basically have to take a low quality screenshot about every 30 milliseconds. The script is attached to a camara.
What I want to do is reduce the render texture size. The way the code is right now changing either W or H basically gets me a SECTION of of all that is being seen by the camara instead of a reduced size version. So my question is how can I resized or downsample what is read into the screenshot (Texture2D) but that it still is a representation of the entire screen.
public class CameraRenderToImage : MonoBehaviour
{
private RemoteRenderServer rrs;
void Start(){
TimeStamp.SetStart();
Camera.onPostRender += OnPostRenderCallback;
}
void OnPostRenderCallback(Camera cam){
if (TimeStamp.HasMoreThanThisEllapsed(30)){
TimeStamp.SetStart();
int W = Screen.width;
int H = Screen.height;
Texture2D screenshot = new Texture2D(W,H, TextureFormat.RGB24, false);
screenshot.ReadPixels( new Rect(0, 0, W,H), 0, 0);
byte[] bytes = screenshot.EncodeToPNG();
System.IO.File.WriteAllBytes("check_me_out.png", bytes);
TimeStamp.Tok("Encode to PNG and Save");
}
}
// Remove the onPostRender callback
void OnDestroy()
{
Camera.onPostRender -= OnPostRenderCallback;
}
}
If you need to resize your render texture from script you can refer to the next code snippet
void Resize(RenderTexture renderTexture, int width, int height) {
if (renderTexture) {
renderTexture.Release();
renderTexture.width = width;
renderTexture.height = height;
}
}
To make it possible to resize the render texture you first need to make sure it is released.
To get Texture2d:
private Texture2D ToCompressedTexture(ref RenderTexture renderTexture)
{
var texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
var previousTarget = RenderTexture.active;
RenderTexture.active = renderTexture;
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
RenderTexture.active = previousTarget;
texture.Compress(false);
texture.Apply(false, true);
renderTexture.Release();
renderTexture = null;
return texture;
}

Image flickers for split-second during FadeTransition - Javafx

I'm currently trying to build a game, and I have an intro sequence of images with accompanying text for the background story of the game. In the beginning, I fade in an image with accompanying text, and then fade both out. Then, I begin the next image-text pairing once the previous fade is complete, and I do this until the background story is complete, but when I do that the image and text flicker for a split-second before the fade in begins for every image and text. I've tried a number of things but can't seem to get rid of the flicker, can anyone help?
This is the function I use for this part in the intro:
private void backgroundStory (Stage stage, MediaPlayer mediaPlayer, String nameEntry, int width, int height, Color color) {
Group backstoryRoot = changeScene(stage, width, height, color);
GridPane backstoryPane = new GridPane();
backstoryRoot.getChildren().add(backstoryPane);
Label storyLabel1 = createLabel("Sometimes, life can get monotonous...");
backstoryPane.getColumnConstraints().add(new ColumnConstraints(width));
RowConstraints initialConstraint = new RowConstraints ((height/2)+20);
backstoryPane.getRowConstraints().add(initialConstraint);
int fadeDuration = 4000;
FadeTransition storyTextTransition1 = storyTextFade(storyLabel1, fadeDuration);
backstoryPane.getChildren().add(storyLabel1);
GridPane.setValignment(storyLabel1, VPos.BOTTOM);
GridPane.setHalignment(storyLabel1, HPos.CENTER);
storyTextTransition1.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
backstoryPane.getChildren().remove(storyLabel1);
backstoryPane.getRowConstraints().remove(initialConstraint);
backstoryPane.getRowConstraints().add(new RowConstraints(25));
VBox vbox = new VBox (10);
backstoryPane.add(vbox, 0, 1);
vbox.setAlignment(Pos.TOP_CENTER);
ImageView dayAndNight = createImage ("Images/Day_And_Night.jpg");
Label storyLabel2 = createLabel("I was living in the city, following the same routine day and night.");
vbox.getChildren().add(dayAndNight);
vbox.getChildren().add(storyLabel2);
storyImageFade(dayAndNight, fadeDuration);
FadeTransition storyTextTransition2 = storyTextFade(storyLabel2, fadeDuration);
String officeReception = "Images/Office_Reception.jpg";
String receptionText = "Seeing the same faces every morning.";
FadeTransition storyTextTransition3 = nextPicture (storyTextTransition2, officeReception, receptionText, fadeDuration, vbox);
String office = "Images/Office.jpg";
String officeText = "Doing the same work every day.";
FadeTransition storyTextTransition4 = nextPicture (storyTextTransition3, office, officeText, fadeDuration, vbox);
}
});
//mediaPlayer.stop();
//introExplanation (stage, nameEntry, width, height, color);
}
These are the functions that are called within it:
private Label createLabel(String labelText) {
Label storyLabel = new Label(labelText);
Font storyFont = Font.font( "Blackadder ITC", 25 );
storyLabel.setTextFill(Color.INDIANRED);
storyLabel.setFont(storyFont);
return storyLabel;
}
private FadeTransition storyTextFade(Label label, int duration) {
FadeTransition storyTransition = new FadeTransition(Duration.millis(duration), label);
storyTransition.setFromValue(0);
storyTransition.setToValue(1);
storyTransition.setCycleCount(2);
storyTransition.setAutoReverse(true);
storyTransition.play();
return storyTransition;
}
private void storyImageFade(ImageView image, int duration) {
FadeTransition imageTransition = new FadeTransition(Duration.millis(duration), image);
imageTransition.setFromValue(0);
imageTransition.setToValue(1);
imageTransition.setCycleCount(2);
imageTransition.setAutoReverse(true);
imageTransition.play();
}
private ImageView createImage (String imageName) {
Image image = new Image(imageName);
ImageView imageview = new ImageView(image);
imageview.setFitWidth(500);
imageview.setFitHeight(500);
//imageview.setPreserveRatio(true);
imageview.setSmooth(true);
imageview.setCache(true);
return imageview;
}
private FadeTransition nextPicture (FadeTransition transition, String image, String imageLabel, int fadeDuration, VBox vbox) {
ArrayList<FadeTransition> transitionList = new ArrayList<FadeTransition>();
transition.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
vbox.getChildren().clear();
ImageView imageview = createImage (image);
storyImageFade(imageview, fadeDuration);
Label storyLabel = createLabel(imageLabel);
FadeTransition storyTextTransition = storyTextFade(storyLabel, fadeDuration);
transitionList.add(storyTextTransition);
vbox.getChildren().add(imageview);
vbox.getChildren().add(storyLabel);
}
});
return transitionList.get(0);
}
Thanks!
This is my first response, so I do apologize if I'm not responding appropriately.
I was facing the same issue when transitioning between scenes. My solution was to set the node opacity to 0 before adding the node to the container.
For your case, it appears as though all of your labels and images are created in the createLabel and createImage methods, and the resulting values are what are being faded in.
private Label createLabel(String labelText) {
Label storyLabel = new Label(labelText);
Font storyFont = Font.font( "Blackadder ITC", 25 );
storyLabel.setTextFill(Color.INDIANRED);
storyLabel.setFont(storyFont);
// Set the opacity before returning the object
storyLabel.setOpacity(0);
return storyLabel;
}
private ImageView createImage (String imageName) {
Image image = new Image(imageName);
ImageView imageview = new ImageView(image);
imageview.setFitWidth(500);
imageview.setFitHeight(500);
//imageview.setPreserveRatio(true);
imageview.setSmooth(true);
imageview.setCache(true);
// Set the opacity before returning the object
imageview.setOpacity(0);
return imageview;
}
I hope this helps.

Take photo in unity c#

I'm trying to build a program that takes your photo and places it with a different background, like a monument or so. So far, I was able to turn the camera on when I start the project with this code
webcamTexture = new WebCamTexture();
rawImage.texture = webcamTexture;
rawImage.material.mainTexture = webcamTexture;
webcamTexture.Play();
Texture2D PhotoTaken = new Texture2D (webcamTexture.width, webcamTexture.height);
PhotoTaken.SetPixels (webcamTexture.GetPixels ());
PhotoTaken.Apply ();
However, I can't take a screenshot or photo because it always ends up all black. I've tried different codes but nothing is working. Can someone please help? Thanks
EDIT
After some tries, this is the code I have:
WebCamTexture webcamTexture;
public RawImage rawImage;
void Start () {
webcamTexture = new WebCamTexture();
rawImage.texture = webcamTexture;
rawImage.material.mainTexture = webcamTexture;
webcamTexture.Play();
RenderTexture texture= new RenderTexture(webcamTexture.width, webcamTexture.height,0);
Graphics.Blit(webcamTexture, texture);
Button btn = yourButton.GetComponent<Button>();
btn.onClick.AddListener(OnClick);
}
public IEnumerator Coroutine(){
yield return new WaitForEndOfFrame ();
}
public void OnClick() {
var width = 767;
var height = 575;
Texture2D texture = new Texture2D(width, height);
texture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
texture.Apply();
// Encode texture into PNG
var bytes = texture.EncodeToPNG();
//Destroy(texture);
File.WriteAllBytes (Application.dataPath + "/../SavedScreen.png", bytes);
}
and with this next code the screenshot is taken, but it takes a photo of the whole thing, and not just a bit of the screen.
void Start()
{
// Set the playback framerate!
// (real time doesn't influence time anymore)
Time.captureFramerate = frameRate;
// Find a folder that doesn't exist yet by appending numbers!
realFolder = folder;
int count = 1;
while (System.IO.Directory.Exists(realFolder))
{
realFolder = folder + count;
count++;
}
// Create the folder
System.IO.Directory.CreateDirectory(realFolder);
}
void Update()
{
// name is "realFolder/shot 0005.png"
var name = string.Format("{0}/shot {1:D04}.png", realFolder, Time.frameCount);
// Capture the screenshot
Application.CaptureScreenshot(name, sizeMultiplier);
}
}
You can take a screenshot like this in Unity
Application.CaptureScreenshot("Screenshot.png");
Reference
EDIT 1
To take a screenshot on a specific part of the screen use the following script:
var width = 400;
var height = 300;
var startX = 200;
var startY = 100;
var tex = new Texture2D (width, height, TextureFormat.RGB24, false);
tex.ReadPixels (Rect(startX, startY, width, height), 0, 0);
tex.Apply ();
// Encode texture into PNG
var bytes = tex.EncodeToPNG();
Destroy(tex);
File.WriteAllBytes(Application.dataPath + "/../SavedScreen.png", bytes);
Reference

Image in mode mosaic in PdfPCell

I am currently using itextPdf library to generate PDF file.
For to set an image I used this solution of itextpdf.com
Now I want to set a small size image as a background in PdfPCell in mode mosaic : if cell have 3 x ImageSize, in PDF I will have my image repeated 3 times in cell
How I can do it ?
this is my example
public class ImageBackgroundEvent implements PdfPCellEvent {
protected Image image;
protected boolean mosaic;
protected boolean full;
public ImageBackgroundEvent(Image image, boolean mosaic, boolean full) {
this.image = image;
this.mosaic = mosaic;
this.full = full;
}
public void cellLayout(PdfPCell cell, Rectangle position,
PdfContentByte[] canvases) {
try {
PdfContentByte cb = canvases[PdfPTable.BACKGROUNDCANVAS];
if(full){
cell.setImage(image);
}
else if(mosaic){
float imgWidth = image.getWidth();
float imgHeight = image.getHeight();
float cellWidth = cell.getWidth();
float cellHeight = cell.getHeight();
if(imgHeight < cellHeight && imgWidth < cellWidth){
PdfPatternPainter pattern = cb.createPattern(imgWidth, imgHeight);
pattern.addImage(image);
pattern.setPatternMatrix(-0.5f, 0f, 0f, 0.5f, 0f, 0f);
cb.setPatternFill(pattern);
//cb.ellipse(180, 408, 450, 534);
cb.fillStroke();
} else{
image.scaleAbsolute(position);
image.setAbsolutePosition(position.getLeft(), position.getBottom());
cb.addImage(image);
}
} else{
image.scaleAbsolute(position);
image.setAbsolutePosition(position.getLeft(), position.getBottom());
cb.addImage(image);
}
} catch (DocumentException e) {
throw new ExceptionConverter(e);
}
}
}
Please take a look at the TiledBackgroundColor example. It takes an image of a light bulb and uses it to define a pattern color:
PdfContentByte canvas = writer.getDirectContent();
Image image = Image.getInstance(IMG);
PdfPatternPainter img_pattern = canvas.createPattern(
image.getScaledWidth(), image.getScaledHeight());
image.setAbsolutePosition(0, 0);
img_pattern.addImage(image);
BaseColor color = new PatternColor(img_pattern);
Now you can use that color for the background of your cell:
PdfPCell cell = new PdfPCell();
cell.setFixedHeight(60);
cell.setBackgroundColor(color);
table.addCell(cell);
The result looks like this: tiled_patterncolor.pdf
Or you could add the image in a cell event as shown in the TiledBackground example. This example was written in answer to the question iTextSharp. Why cell background image is rotated 90 degrees clockwise?
I've written a variation on this example: TiledBackgroundColor2
The event looks like this:
class TiledImageBackground implements PdfPCellEvent {
protected Image image;
public TiledImageBackground(Image image) {
this.image = image;
}
public void cellLayout(PdfPCell cell, Rectangle position,
PdfContentByte[] canvases) {
try {
PdfContentByte cb = canvases[PdfPTable.BACKGROUNDCANVAS];
image.scaleToFit(10000000, position.getHeight());
float x = position.getLeft();
float y = position.getBottom();
while (x + image.getScaledWidth() < position.getRight()) {
image.setAbsolutePosition(x, y);
cb.addImage(image);
x += image.getScaledWidth();
}
} catch (DocumentException e) {
throw new ExceptionConverter(e);
}
}
}
As you see, I don't care about the actual dimensions of the image. I scale the image in such a way that it fits the height of the cell. I don't use a pattern color either. I just add the image as many time as it fits the width of the cell.
This is how I declare the event to the cell:
PdfPCell cell = new PdfPCell();
Image image = Image.getInstance(IMG);
cell.setCellEvent(new TiledImageBackground(image));
The result looks like this:
Many variations are possible depending on your exact requirement.

live wallpaper background image is bigger than screen size andEngine

I want to use one image for all screen, but if i load bigger image than screen size it is not visible. image size is 1280x720, screen size is 960x540. What can i do?
Code:
public EngineOptions onCreateEngineOptions() {
final DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(displayMetrics);
wm.getDefaultDisplay().getRotation();
CAMERA_WIDTH = displayMetrics.widthPixels;
CAMERA_HEIGHT = displayMetrics.heightPixels;
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new EngineOptions(true, ScreenOrientation.PORTRAIT_FIXED, new FillResolutionPolicy(), this.mCamera);}
next:
public void onCreateResources(OnCreateResourcesCallback createResourcesCallback) throws Exception {
final BuildableBitmapTextureAtlas bitmapTextureAtlas = new BuildableBitmapTextureAtlas(
mEngine.getTextureManager(), CAMERA_WIDTH, CAMERA_HEIGHT,
TextureOptions.BILINEAR);
mTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(bitmapTextureAtlas, this, "gfx/h720x1280a.png");
}
Its better to make scale it to support all screens:
int spriteWidth = 1280;
int spriteHeight = 720;
int spriteScaleX = spriteWidth/screenWidth;
int spriteScaleY = spriteHeight/screenHeight;
place this factor as scale to your background sprite.It will support to all devices.
You need a image that maintain the ratio of your camera width and height, Its not needed to use large resolution image , OpenGL has the capability to maintain the quality of the image.