Finding first and last line and column with non-transparent pixels?

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
myxal
Posts: 3
Joined: 2017-05-14T06:46:46-07:00
Authentication code: 1151

Finding first and last line and column with non-transparent pixels?

Post by myxal »

Hi all.
I have many png files which are used as textures in a game and thus have their dimensions in a power of 2, even when the image itself is smaller. Is there a script for $(SUBJ)? All the transparent pixels are 0,0,0,0 RGBA. In the end, I need to convert the line/column numbers to floats between 0 and 1, proportional to texture size:

Code: Select all

<Element name="freezer_open.tex" u1="0.09765625" u2="0.7990234375" v1="0.109765625" v2="0.69934375" />
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Finding first and last line and column with non-transparent pixels?

Post by snibgo »

Please say what version IM you use, on what platform, and link to an example image.

How large are the images?

A possible algorithm is:

1. Extract the alpha. Change non-black to white. Now the image is black and white only, and the task is to find the first and last columns with white pixels.

2. Crop into lines (so we have HH images, each WWx1 pixels), and evaluate-sequence max. Now we have one image, WWx1 pixels, and the task is to find the first and last white pixel.

3. Add a 1-pixel black border.

4. Use "format %@" to find the left-most white pixel, and width to the right-most white pixel.

5. Simple arithmetic converts the previous two numbers into coordinates.
snibgo's IM pages: im.snibgo.com
myxal
Posts: 3
Joined: 2017-05-14T06:46:46-07:00
Authentication code: 1151

Re: Finding first and last line and column with non-transparent pixels?

Post by myxal »

Hi.
Regarding version - 6.9.8-5 from brew (macOS 10.12.4).

I was googling around in the meantime, and

Code: Select all

convert ... -trim 
is able to output info on where it would trim the image. I'll see if I can make a shell script to do the work with that. So far it seems to be able to do exactly what I'm looking for, but it turns out the mod I'm trying to fix doesn't have a clean texture image to begin with. :roll:
myxal
Posts: 3
Joined: 2017-05-14T06:46:46-07:00
Authentication code: 1151

Re: Finding first and last line and column with non-transparent pixels?

Post by myxal »

Right, this should do it:

Code: Select all

#!/bin/bash
# set -x
set -e
_scale=8

while (($#)); do
  FILE="$1"
  bounds=( $(convert "$FILE" -trim info:- | cut -d ' ' -f 3,4) )
  echo "File: " $FILE
  echo "Size: " ${bounds[0]}
  _new_x=${bounds[0]%%x*}
  _new_y=${bounds[0]##*x}
  echo "Geometry: " ${bounds[1]}
  _orig_x=${bounds[1]%%x*}
  _orig_y=${bounds[1]%%+*}
  _orig_y=${_orig_y##*x}
  _offset_x=${bounds[1]#*+}
  _offset_x=${_offset_x%%+*}
  _offset_y=${bounds[1]##*+}
  # u1 - left edge distance from left
  # u2 - right edge distance from left
  # v1 - bottom edge distance from bottom
  # v2 - top edge distance from bottom
  echo u1 = "$(bc -l <<< "scale=$_scale; $_offset_x/$_orig_x")"
  echo u2 = "$(bc -l <<< "scale=$_scale; ($_offset_x + $_new_x)/$_orig_x")"
  echo v1 = "$(bc -l <<< "scale=$_scale; 1 - ($_offset_y + $_new_y)/$_orig_x")"
  echo v2 = "$(bc -l <<< "scale=$_scale; 1 - $_offset_y/$_orig_x")"
  shift
done
Caveats:
  • Files with spaces aren't handled.
Post Reply