0

Merge remote branch 'origin/resize'

This commit is contained in:
Andrew Chin
2012-07-20 22:22:44 -04:00
4 changed files with 163 additions and 2 deletions

View File

@@ -489,3 +489,154 @@ draw_triangle(PyObject *dest, int inclusive,
return dest; return dest;
} }
/* scales the image to half size
*/
inline PyObject *
resize_half(PyObject *dest, PyObject *src) {
/* libImaging handles */
Imaging imDest, imSrc;
/* alpha properties */
int src_has_alpha, dest_has_alpha;
/* iteration variables */
unsigned int x, y;
/* temp color variables */
unsigned int r, g, b, a;
/* size values for source and destination */
int src_width, src_height, dest_width, dest_height;
imDest = imaging_python_to_c(dest);
imSrc = imaging_python_to_c(src);
if (!imDest || !imSrc)
return NULL;
/* check the various image modes, make sure they make sense */
if (strcmp(imDest->mode, "RGBA") != 0) {
PyErr_SetString(PyExc_ValueError,
"given destination image does not have mode \"RGBA\"");
return NULL;
}
if (strcmp(imSrc->mode, "RGBA") != 0 && strcmp(imSrc->mode, "RGB") != 0) {
PyErr_SetString(PyExc_ValueError,
"given source image does not have mode \"RGBA\" or \"RGB\"");
return NULL;
}
src_width = imSrc->xsize;
src_height = imSrc->ysize;
dest_width = imDest->xsize;
dest_height = imDest->ysize;
/* make sure destination size is 1/2 src size */
if (src_width / 2 != dest_width || src_height / 2 != dest_height) {
PyErr_SetString(PyExc_ValueError,
"destination image size is not one-half source image size");
return NULL;
}
/* set up flags for the src/mask type */
src_has_alpha = (imSrc->pixelsize == 4 ? 1 : 0);
dest_has_alpha = (imDest->pixelsize == 4 ? 1 : 0);
/* check that there remains anything to resize */
if (dest_width <= 0 || dest_height <= 0) {
/* nothing to do, return */
return dest;
}
/* set to fully opaque if source has no alpha channel */
if(!src_has_alpha)
a = 0xFF << 2;
for (y = 0; y < dest_height; y++) {
UINT8 *out = (UINT8 *)imDest->image[y];
UINT8 *in_row1 = (UINT8 *)imSrc->image[y * 2];
UINT8 *in_row2 = (UINT8 *)imSrc->image[y * 2 + 1];
for (x = 0; x < dest_width; x++) {
// read first column
r = *in_row1;
r += *in_row2;
in_row1++;
in_row2++;
g = *in_row1;
g += *in_row2;
in_row1++;
in_row2++;
b = *in_row1;
b += *in_row2;
in_row1++;
in_row2++;
if (src_has_alpha)
{
a = *in_row1;
a += *in_row2;
in_row1++;
in_row2++;
}
// read second column
r += *in_row1;
r += *in_row2;
in_row1++;
in_row2++;
g += *in_row1;
g += *in_row2;
in_row1++;
in_row2++;
b += *in_row1;
b += *in_row2;
in_row1++;
in_row2++;
if (src_has_alpha)
{
a += *in_row1;
a += *in_row2;
in_row1++;
in_row2++;
}
// write blended color
*out = (UINT8)(r >> 2);
out++;
*out = (UINT8)(g >> 2);
out++;
*out = (UINT8)(b >> 2);
out++;
if (dest_has_alpha)
{
*out = (UINT8)(a >> 2);
out++;
}
}
}
return dest;
}
/* wraps resize_half so it can be called directly from python */
PyObject *
resize_half_wrap(PyObject *self, PyObject *args)
{
/* raw input python variables */
PyObject *dest, *src;
/* return value: dest image on success */
PyObject *ret;
if (!PyArg_ParseTuple(args, "OO", &dest, &src))
return NULL;
ret = resize_half(dest, src);
if (ret == dest) {
/* Python needs us to own our return value */
Py_INCREF(dest);
}
return ret;
}

View File

@@ -26,6 +26,9 @@ static PyMethodDef COverviewerMethods[] = {
{"alpha_over", alpha_over_wrap, METH_VARARGS, {"alpha_over", alpha_over_wrap, METH_VARARGS,
"alpha over composite function"}, "alpha over composite function"},
{"resize_half", resize_half_wrap, METH_VARARGS,
"downscale image to half size"},
{"render_loop", chunk_render, METH_VARARGS, {"render_loop", chunk_render, METH_VARARGS,
"Renders stuffs"}, "Renders stuffs"},

View File

@@ -69,6 +69,8 @@ PyObject *draw_triangle(PyObject *dest, int inclusive,
int x2, int y2, int x2, int y2,
unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r2, unsigned char g2, unsigned char b2,
int tux, int tuy, int *touchups, unsigned int num_touchups); int tux, int tuy, int *touchups, unsigned int num_touchups);
PyObject *resize_half(PyObject *dest, PyObject *src);
PyObject *resize_half_wrap(PyObject *self, PyObject *args);
/* forward declaration of RenderMode object */ /* forward declaration of RenderMode object */
typedef struct _RenderMode RenderMode; typedef struct _RenderMode RenderMode;

View File

@@ -35,6 +35,7 @@ from .files import FileReplacer
from .optimizeimages import optimize_image from .optimizeimages import optimize_image
import rendermodes import rendermodes
import c_overviewer import c_overviewer
from c_overviewer import resize_half
""" """
@@ -859,13 +860,17 @@ class TileSet(object):
# Create the actual image now # Create the actual image now
img = Image.new("RGBA", (384, 384), self.options['bgcolor']) img = Image.new("RGBA", (384, 384), self.options['bgcolor'])
# we'll use paste (NOT alpha_over) for quadtree generation because # we'll use paste (NOT alpha_over) for quadtree generation because
# this is just straight image stitching, not alpha blending # this is just straight image stitching, not alpha blending
for path in quadPath_filtered: for path in quadPath_filtered:
try: try:
quad = Image.open(path[1]).resize((192,192), Image.ANTIALIAS) #quad = Image.open(path[1]).resize((192,192), Image.ANTIALIAS)
src = Image.open(path[1])
src.load()
quad = Image.new("RGBA", (192, 192), self.options['bgcolor'])
resize_half(quad, src)
img.paste(quad, path[0]) img.paste(quad, path[0])
except Exception, e: except Exception, e:
logging.warning("Couldn't open %s. It may be corrupt. Error was '%s'", path[1], e) logging.warning("Couldn't open %s. It may be corrupt. Error was '%s'", path[1], e)