How to change format of texture at runtime in unity3d [duplicate] - format

I have a Textured2D loaded which is represented in ETC_RGB4 how can I change this to another format? say RGBA32. Basically I want to switch from 3 channels to 4 and from 4 bit per channel to 8 per channel.
Thanks

You can change texture format during run-time.
1.Create new empty Texture2D and provide RGBA32 to the TextureFormat argument. This will create an empty texture with the RGBA32 format.
2.Use Texture2D.GetPixels to obtain the pixels of the old texture that's in ETC_RGB4 format then use Texture2D.SetPixels to put those pixels in the newly created Texture from #1.
3.Call Texture2D.Apply to apply the changes. That's it.
A simple extension method for this:
public static class TextureHelperClass
{
public static Texture2D ChangeFormat(this Texture2D oldTexture, TextureFormat newFormat)
{
//Create new empty Texture
Texture2D newTex = new Texture2D(2, 2, newFormat, false);
//Copy old texture pixels into new one
newTex.SetPixels(oldTexture.GetPixels());
//Apply
newTex.Apply();
return newTex;
}
}
USAGE:
public Texture2D theOldTextue;
// Update is called once per frame
void Start()
{
Texture2D RGBA32Texture = theOldTextue.ChangeFormat(TextureFormat.RGBA32);
}

Related

How can I add "proper" images (not Icons) to my JFrame/JPanel/JComponents (Swing) (Kotlin)

Language: Kotlin,
GUI Library: Swing,
IDE: IntelliJ IDEA
I know that there are similarly phrased questions, but note that I want to add multiple images, not just one, to any type of JComponent that holds other components. For example, I am not concerned with adding an image to a JLabel, I already know how to do that. I want to know how to add an image to a JFrame, JPanel, Container, etc.; all things that hold other Components (and have an add(Component) function). Finally, I don't want that workaround where you add the image to a JLabel with no text and then add that to the container. I would like to just use the Image class or a subset like BufferedImage or URL.
I want to be able to call the add() method from the Container class, jFrame.add(component) for example, where component is some sort of image. I want this to result in an image being displayed on the screen.
The ImageIcon class is not a Component so this can't be input on its own. I think I would have to create some sort of custom Image class that extends from Component or JComponent, but I don't know what I would have to override to get that to display an image on screen when added to another JComponent. There are multiple solutions to this, but to clarify, I don't want some kind of "middle man" where I add a JLabel or JButton or something that only contains an Icon. I don't want to display icons anyway, I want to display full-sized images anywhere on the screen. I will provide a possible example of what I want the final result to look like.
class MyApp() {
fun init() {
var jFrame = JFrame()
jFrame.add(Image("filepath/image.png"))
//Some other JFrame boiler plate
jFrame.isVisible = true
}
}
fun main() {
MyApp().init()
}
The unclear part is the Image class, and whether that's a custom class that inherits JImage, or some already defined class or method I don't know about. I know about ImageIO and BufferedImage and ImageIcon, but none of them directly go into this method, as they don't inherit Component or JComponent.
EDIT:
I tried using Camickr's second solution, but it didn't work. I will post the code to see if a made a simple mistake.
import java.awt.Image as AWTImage
import java.awt.Image.*
//Including these imports as I used name alias so I had to say what it was from.
open class JImage(var point: Point = Point(0, 0), image: AWTImage): JComponent() {
var image: ImageIcon = ImageIcon(image)
override fun paintComponent(g: Graphics?) {
super.paint(g)
g?.drawImage(image.image, point.x.toInt(), point.y.toInt(), null)
}
}
class SplashScreen(image: JImage): Frame() {
init {
//jFrame.isUndecorated = true
jFrame.add(image)
}
}
class MyApp {
fun init() {
var jFrame = SplashScreen(JImage(image = ImageIO.read(Loader().getClassLoader().getResourceAsStream("resources/images/splashscreen/SplashScreen.png"))).getScaledInstance(Size(1000, 1000*3/5)))
jFrame.isVisible = true
}
}
fun main() {
MyApp().init()
}
FINAL EDIT:
Okay, so I did make a simple mistake when trying this solution. I overrode paintComponent() but then inside it, I called super.paint(). Additionally, I realized I didn't have to use the ImageIcon class, which I didn't want to do anyway. This is the Image class I have come up with.
open class JImage(var point: Point = Point(0, 0), var image: AWTImage): JComponent() {
fun getScaledInstance(size: Size, scalingMethods: ScalingMethods = ScalingMethods.DEFAULT): JImage {
val scale: Int = when(scalingMethods) {
ScalingMethods.DEFAULT -> SCALE_DEFAULT
ScalingMethods.FAST -> SCALE_FAST
ScalingMethods.AREA_AVERAGING -> SCALE_AREA_AVERAGING
ScalingMethods.REPLICATE -> SCALE_REPLICATE
ScalingMethods.SMOOTH -> SCALE_SMOOTH
}
return JImage(point, image.getScaledInstance(size.width.toInt(), size.height.toInt(), scale))
}
override fun paintComponent(g: Graphics?) {
super.paintComponent(g)
g?.drawImage(image, point.x.toInt(), point.y.toInt(), null)
}
}
I want to know how to add an image to a JFrame, JPanel, Container, etc.
You don't add an image to a JFrame, JPanel etc. As you said an image is not a component. You add the image to a JLabel and add the label to the panel. This is the easiest and more direct way to display an image at its actual size.
Don't know if Kotlin is any different, but the other option is to do custom painting and paint the image on a JPanel by overriding the paintComponent(…) method and using the Graphics.drawImage(…) method and then add the panel to the frame. Read the Swing tutorial on Custom Painting for painting basics.
You can also check out Background Panel for an example that paints an image as a background of the panel. The image can be:
painted at its real size
scaled to fill the panel
tiled to fill the panel
Just note that the image should NOT be read in the paintComponent() method as painting code should be efficient.

Get co-ordinates of image in pdf

In my project, I want to find co-ordinates of image in pdf. I tried searching itext and pdfbox, but I was not succesful. Using these co-ordinates and extracted image, I want to verify whether the extracted image is same as image present in database, and co-ordinates of image are same as present in database.
When you say that you've tried with iText, I assume that you've used the ExtractImages example as the starting point for your code. This example uses the helper class MyImageRenderListener, which implements the RenderListener interface.
In that helper class the renderImage() method is implemented like this:
public void renderImage(ImageRenderInfo renderInfo) {
try {
String filename;
FileOutputStream os;
PdfImageObject image = renderInfo.getImage();
if (image == null) return;
filename = String.format(path, renderInfo.getRef().getNumber(), image.getFileType());
os = new FileOutputStream(filename);
os.write(image.getImageAsBytes());
os.flush();
os.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
It uses the ImageRenderInfo object to obtain a PdfImageObject instance and it creates an image file using that object.
If you inspect the ImageRenderInfo class, you'll discover that you can also ask for other info about the image. What you need, is the getImageCTM() method. This method returns a Matrix object. This matrix can be interpreted using ordinary high-school algebra. The values I31 and I32 give you the X and Y position. In most cases I11 and I22 will give you the width and the height (unless the image is rotated).
If the image is rotated, you'll have to consult your high-school schoolbooks, more specifically the ones discussing analytic geometry.

How to cache TextureAtlas results?

When using a TextureAtlas to create a Sprite with the createSprite method, the LibGDX documentation says: This method uses string comparison to find the region and constructs a new sprite, so the result should be cached rather than calling this method multiple times.
How do I cache these results? Is it just a variable I create to store the created sprite? If so then how do I create different copies of the same sprite?
Each time you use the createSprite method, a new Sprite gets created. Usually you'd have one sprite per enemy for example. Let's say that you have a class Frog which is one of your enemies. It should look like this (pseudo-code):
public class Frog {
private Sprite sprite;
public Frog(TextureAtlas atlas) {
sprite = atlas.createSprite("frog");
}
public void update(float deltaTime) {
// update the sprite position
}
public void render(Batch batch) {
sprite.draw(batch);
}
}
Now each Frog would have its own Sprite. This is necessary, since all frogs can be in different places. The position will be configured via the Sprite. You will create the sprite just once in the constructor and all of those sprites share the same TextureRegion of the same TextureAtlas, which will result in a good performance, since there won't be many texture switches on the graphics card, when you render your frogs.

Load texture resized in XNA

I'm developing for Windows Phone XNA and would like to load textures with a smaller size to decrease memory impact where the full image isn't required.
My current solution is to use a rendertarget to draw and return that rendertarget as a smaller texture to use:
public static Texture2D LoadResized(string texturePath, float scale)
{
Texture2D texLoaded = Content.Load<Texture2D>(texturePath);
Vector2 resizedSize = new Vector2(texLoaded.Width * scale, texLoaded.Height * scale);
Texture2D resized = ResizeTexture(texLoaded, resizedSize);
//texLoaded.Dispose();
return resized;
}
public static Texture2D ResizeTexture(Texture2D toResize, Vector2 targetSize)
{
RenderTarget2D renderTarget = new RenderTarget2D(
GraphicsDevice, (int)targetSize.X, (int)targetSize.Y);
Rectangle destinationRectangle = new Rectangle(
0, 0, (int)targetSize.X, (int)targetSize.Y);
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.Clear(Color.Transparent);
SpriteBatch.Begin();
SpriteBatch.Draw(toResize, destinationRectangle, Color.White);
SpriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
return renderTarget;
}
This works in that the texture gets resized but from memory usage it looks like the Texture "texLoaded" doesn't get freed. When using the uncommented Dispose method the SpriteBatch.End() will throw a disposed exception.
Any other way to load the texture resized for less memory usage?
Your code is almost ok. There's a minor bug in it.
You'll probably notice that it only throws that exception the second time that you call LoadResized for any given texture. This is because ContentManager keeps an internal cache of content that it loads - it "owns" everything that it loads. That way, if you load something twice, it just gives you back the cached object. By calling Dispose you are disposing the object in its cache!
The solution, then, is to not use ContentManager to load your content - at least not the default implementation. You can inherit your own class from ContentManager that does not cache items, like so (code is based on this blog post):
class FreshLoadContentManager : ContentManager
{
public FreshLoadContentManager(IServiceProvider s) : base(s) { }
public override T Load<T>(string assetName)
{
return ReadAsset<T>(assetName, (d) => { });
}
}
Pass in Game.Services to create one. Don't forget to set the RootDirectory property.
Then use this derived content manager to load your content. You now can safely (and now should!) Dispose of all content that you load from it yourself.
You may also wish to attach an event handler to the RenderTarget2D.ContentLost event, so that, in the event the graphics device is "lost", the resized texture gets recreated.

Clone an Image in Flex 4.6

For the past few hours I have been trying to clone an image in Flex (using the Spark Components, but also trying to convert between Bitmap and BitmapImage).
What I am trying exactly is to create a simple painting application which keeps track of each Brush-Stroke. As soon as the Image on the Canvas has changed, it is to be cloned and then the clone is to be put into the History-Panel on the bottom of the application.
Things I have tried include:
Using ObjectUtils.clone(Object)
Creating BitmapData from Image.content, then making it a Bitmap and simply display it (Image doesn't have a content field, it says)
Performing a byte-copy
and others I could find on the internet, of course.
So basically, how does one clone an Image (Spark Image) in Flex 4.6?
Thank you very much!
-- Danny Nophut
Instead of cloning you can get the image of the drawing and set the bitmap of the image as source to the history image, do some thing like this
private function getBitmapData( target:DisplayObject ) : BitmapData
{
//target.width and target.height can also be replaced with a fixed number.
var bd : BitmapData = new BitmapData( target.width, target.height );
bd.draw( target );
return bd;
}
In some case if the width and height of the target is not working you can use the getbounds method to get the bounds of the object and from the bounds take the width and height.
There's a clone function on a bitmapdata:
public class EZB2ParkObject extends Image implements IEZB2ParkObject
{
public function clone():IEZB2ParkObject{
var n:IEZB2ParkObject = new EZB2ParkObject();
n.id = this.id;
n.source = new Bitmap(BitmapData(this.source.bitmapData).clone());
n.dimensions = this.dimensions;
n.assetId = this.assetId;
return n;
}
}

Resources