Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render themes: PNG scaling #1091

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -51,7 +51,7 @@ public interface GraphicFactory {
PointTextContainer createPointTextContainer(Point xy, Display display, int priority, String text, Paint paintFront, Paint paintBack,
SymbolContainer symbolContainer, Position position, int maxTextWidth);

ResourceBitmap createResourceBitmap(InputStream inputStream, int hash) throws IOException;
ResourceBitmap createResourceBitmap(InputStream inputStream, float scaleFactor, int width, int height, int percent, int hash) throws IOException;

TileBitmap createTileBitmap(InputStream inputStream, int tileSize, boolean isTransparent) throws IOException;

Expand Down
Expand Up @@ -50,6 +50,44 @@ public static int filterColor(int color, Filter filter) {
return (a << 24) | (r << 16) | (g << 8) | b;
}

/**
* Given the original image size, as well as symbol-width/height/percent parameters from the render theme,
* this computes the final image size as it will appear on screen
* @param picWidth original image width
* @param picHeight original image height
* @param scaleFactor scale factor to scale to screen DPI
* @param width width from rendertheme
* @param height height from rendertheme
* @param percent scale percent from rendertheme
* @return
*/
public static float[] computeFinalImageSize(float picWidth, float picHeight, float scaleFactor, int width, int height, int percent) {
float bitmapWidth = picWidth * scaleFactor;
float bitmapHeight = picHeight * scaleFactor;

float aspectRatio = picWidth / picHeight;

if (width != 0 && height != 0) {
// both width and height set, override any other setting
bitmapWidth = width;
bitmapHeight = height;
} else if (width == 0 && height != 0) {
// only width set, calculate from aspect ratio
bitmapWidth = height * aspectRatio;
bitmapHeight = height;
} else if (width != 0 && height == 0) {
// only height set, calculate from aspect ratio
bitmapHeight = width / aspectRatio;
bitmapWidth = width;
}

if (percent != 100) {
bitmapWidth *= percent / 100f;
bitmapHeight *= percent / 100f;
}
return new float[] { bitmapWidth, bitmapHeight };
}

/**
* @param color color value in layout 0xAARRGGBB.
* @return the alpha value for the color.
Expand Down
Expand Up @@ -258,8 +258,8 @@ public PointTextContainer createPointTextContainer(Point xy, Display display, in
}

@Override
public ResourceBitmap createResourceBitmap(InputStream inputStream, int hash) throws IOException {
return new AndroidResourceBitmap(inputStream, hash);
public ResourceBitmap createResourceBitmap(InputStream inputStream, float scaleFactor, int width, int height, int percent, int hash) throws IOException {
return new AndroidResourceBitmap(inputStream, scaleFactor, width, height, percent, hash);
}

@Override
Expand Down
Expand Up @@ -20,6 +20,7 @@
import android.graphics.BitmapFactory;
import android.util.Pair;

import org.mapsforge.core.graphics.GraphicUtils;
import org.mapsforge.core.graphics.ResourceBitmap;

import java.io.IOException;
Expand Down Expand Up @@ -68,7 +69,7 @@ public static void clearResourceBitmaps() {
}
}

private static android.graphics.Bitmap getResourceBitmap(InputStream inputStream, int hash) throws IOException {
private static android.graphics.Bitmap getResourceBitmap(InputStream inputStream, float scaleFactor, int width, int height, int percent, int hash) throws IOException {
synchronized (RESOURCE_BITMAPS) {
Pair<android.graphics.Bitmap, Integer> data = RESOURCE_BITMAPS.get(hash);
if (data != null) {
Expand All @@ -82,6 +83,9 @@ private static android.graphics.Bitmap getResourceBitmap(InputStream inputStream
if (bitmap == null) {
throw new IOException("BitmapFactory failed to decodeStream");
}
float[] finalSize = GraphicUtils.computeFinalImageSize(bitmap.getWidth(), bitmap.getHeight(), scaleFactor, width, height, percent);
if ((int) finalSize[0] != width || (int) finalSize[1] != height)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comparison should be done with bitmap's width and height.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, you are right. Fixed.

bitmap = Bitmap.createScaledBitmap(bitmap, (int) finalSize[0], (int) finalSize[1], true);
Pair<android.graphics.Bitmap, Integer> updated = new Pair<android.graphics.Bitmap, Integer>(bitmap,
Integer.valueOf(1));
RESOURCE_BITMAPS.put(hash, updated);
Expand Down Expand Up @@ -139,9 +143,9 @@ protected AndroidResourceBitmap(int hash) {
this.hash = hash;
}

AndroidResourceBitmap(InputStream inputStream, int hash) throws IOException {
AndroidResourceBitmap(InputStream inputStream, float scaleFactor, int width, int height, int percent, int hash) throws IOException {
this(hash);
this.bitmap = getResourceBitmap(inputStream, hash);
this.bitmap = getResourceBitmap(inputStream, scaleFactor, width, height, percent, hash);
}

// destroy is the super method here, which will take care of bitmap accounting
Expand Down
Expand Up @@ -24,6 +24,8 @@

import com.caverock.androidsvg.SVG;

import org.mapsforge.core.graphics.GraphicUtils;

import java.io.IOException;
import java.io.InputStream;

Expand All @@ -41,34 +43,12 @@ public static android.graphics.Bitmap getResourceBitmap(InputStream inputStream,

double scale = scaleFactor / Math.sqrt((picture.getHeight() * picture.getWidth()) / defaultSize);

float bitmapWidth = (float) (picture.getWidth() * scale);
float bitmapHeight = (float) (picture.getHeight() * scale);

float aspectRatio = (1f * picture.getWidth()) / picture.getHeight();

if (width != 0 && height != 0) {
// both width and height set, override any other setting
bitmapWidth = width;
bitmapHeight = height;
} else if (width == 0 && height != 0) {
// only width set, calculate from aspect ratio
bitmapWidth = height * aspectRatio;
bitmapHeight = height;
} else if (width != 0 && height == 0) {
// only height set, calculate from aspect ratio
bitmapHeight = width / aspectRatio;
bitmapWidth = width;
}

if (percent != 100) {
bitmapWidth *= percent / 100f;
bitmapHeight *= percent / 100f;
}
float[] bmpSize = GraphicUtils.computeFinalImageSize(picture.getWidth(), picture.getHeight(), (float) scale, width, height, percent);

android.graphics.Bitmap bitmap = android.graphics.Bitmap.createBitmap((int) Math.ceil(bitmapWidth),
(int) Math.ceil(bitmapHeight), AndroidGraphicFactory.TRANSPARENT_BITMAP);
android.graphics.Bitmap bitmap = android.graphics.Bitmap.createBitmap((int) Math.ceil(bmpSize[0]),
(int) Math.ceil(bmpSize[1]), AndroidGraphicFactory.TRANSPARENT_BITMAP);
Canvas canvas = new Canvas(bitmap);
canvas.drawPicture(picture, new RectF(0, 0, bitmapWidth, bitmapHeight));
canvas.drawPicture(picture, new RectF(0, 0, bmpSize[0], bmpSize[1]));

return bitmap;
} catch (Exception e) {
Expand Down
Expand Up @@ -194,8 +194,8 @@ public PointTextContainer createPointTextContainer(Point xy, Display display, in
}

@Override
public ResourceBitmap createResourceBitmap(InputStream inputStream, int hash) throws IOException {
return new AwtResourceBitmap(inputStream);
public ResourceBitmap createResourceBitmap(InputStream inputStream, float scaleFactor, int width, int height, int percent, int hash) throws IOException {
return new AwtResourceBitmap(inputStream, scaleFactor, width, height, percent);
}

@Override
Expand Down
Expand Up @@ -15,6 +15,7 @@
*/
package org.mapsforge.map.awt.graphics;

import org.mapsforge.core.graphics.GraphicUtils;
import org.mapsforge.core.graphics.ResourceBitmap;

import java.awt.image.BufferedImage;
Expand All @@ -23,8 +24,10 @@

public class AwtResourceBitmap extends AwtBitmap implements ResourceBitmap {

AwtResourceBitmap(InputStream inputStream) throws IOException {
AwtResourceBitmap(InputStream inputStream, float scaleFactor, int width, int height, int percent) throws IOException {
super(inputStream);
float[] finalSize = GraphicUtils.computeFinalImageSize(getWidth(), getHeight(), scaleFactor, width, height, percent);
scaleTo((int) finalSize[0], (int) finalSize[1]);
}

AwtResourceBitmap(BufferedImage bufferedImage) {
Expand Down
Expand Up @@ -18,6 +18,8 @@
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.app.beans.SVGIcon;

import org.mapsforge.core.graphics.GraphicUtils;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;
Expand All @@ -37,34 +39,12 @@ public static BufferedImage getResourceBitmap(InputStream inputStream, String na

double scale = scaleFactor / Math.sqrt((diagram.getHeight() * diagram.getWidth()) / defaultSize);

float bitmapWidth = (float) (diagram.getWidth() * scale);
float bitmapHeight = (float) (diagram.getHeight() * scale);

float aspectRatio = diagram.getWidth() / diagram.getHeight();

if (width != 0 && height != 0) {
// both width and height set, override any other setting
bitmapWidth = width;
bitmapHeight = height;
} else if (width == 0 && height != 0) {
// only width set, calculate from aspect ratio
bitmapWidth = height * aspectRatio;
bitmapHeight = height;
} else if (width != 0 && height == 0) {
// only height set, calculate from aspect ratio
bitmapHeight = width / aspectRatio;
bitmapWidth = width;
}

if (percent != 100) {
bitmapWidth *= percent / 100f;
bitmapHeight *= percent / 100f;
}
float[] bmpSize = GraphicUtils.computeFinalImageSize(diagram.getWidth(), diagram.getHeight(), (float) scale, width, height, percent);

SVGIcon icon = new SVGIcon();
icon.setAntiAlias(true);
icon.setAutosize(SVGIcon.AUTOSIZE_STRETCH);
icon.setPreferredSize(new Dimension((int) bitmapWidth, (int) bitmapHeight));
icon.setPreferredSize(new Dimension((int) bmpSize[0], (int) bmpSize[1]));
icon.setSvgURI(uri);
BufferedImage bufferedImage = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
icon.paintIcon(null, bufferedImage.createGraphics(), 0, 0);
Expand Down
Expand Up @@ -68,7 +68,7 @@ public static ResourceBitmap createBitmap(GraphicFactory graphicFactory, Display
}
}
try {
return graphicFactory.createResourceBitmap(inputStream, absoluteName.hashCode());
return graphicFactory.createResourceBitmap(inputStream, displayModel.getScaleFactor(), width, height, percent, hash);
} catch (IOException e) {
throw new IOException("Reading bitmap file failed " + src, e);
}
Expand Down