This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
joshmanisdabomb's profile picture

Width And Height Of Paintutils Image

Started by joshmanisdabomb, 22 September 2013 - 05:35 PM
joshmanisdabomb #1
Posted 22 September 2013 - 07:35 PM
How would you find the width and height of a loaded paintutils image. I try to get the length of tables with the # symbol but it doesn't work properly.

function getHeight(image)
  return #image
end

function getWidth(image)
  local imagewidth = 0
  for i=1,#image,1 do
    imagewidth = math.max(#image[i], imagewidth)
  end
  return imagewidth
end
Help would be greatly appreciated. Thank you. :)/>
theoriginalbit #2
Posted 22 September 2013 - 07:58 PM
That should work fine. However if you wish try using table.getn or table.maxn.
joshmanisdabomb #3
Posted 23 September 2013 - 05:32 AM
That should work fine. However if you wish try using table.getn or table.maxn.
Thanks for teaching me something new. Here's a screenshot of what's happening.
The first number is what the program is saying the height of the image is, second number is "width".
The image is obviously the image. There are no black pixels in the image.
MKlegoman357 #4
Posted 23 September 2013 - 09:31 AM
The problem is that when paint program saves the file it saves empty pixels too. When paintutils reads the file it loads those empty pixels.
joshmanisdabomb #5
Posted 23 September 2013 - 09:40 AM
The problem is that when paint program saves the file it saves empty pixels too. When paintutils reads the file it loads those empty pixels.
So is there a way to detect the empty pixels and remove them?
MKlegoman357 #6
Posted 23 September 2013 - 01:04 PM
The problem is that when paint program saves the file it saves empty pixels too. When paintutils reads the file it loads those empty pixels.
So is there a way to detect the empty pixels and remove them?

You could loop them all from right to left and from bottom to top and set the boundaries by checking if current pixel is something different from 0 (0 means transparency in CC image format, an empty pixel).
Edited on 23 September 2013 - 11:05 AM
theoriginalbit #7
Posted 23 September 2013 - 01:19 PM
Ahh so your problem is that it was counting fine, it just wasn't counting how you wanted…. the content. Well for this we actually need to inspect all the elements of the table.

However since some lines don't need to have pixels, but can be part of an image, example

local img = {
  {0;0;0;0;0;0;0;0}; --# this is not part of the image it's just padding the paint program may add
  {0xF;0xF;0xF;0xF;0xF;0xF;0xF;0xF;};
  {0;0;0;0;0;0;0;0}; --# this is still part of the image
  {0xF;0xF;0xF;0xF;0xF;0xF;0xF;0xF;};
}
and then the fact that you may have a valid image that also includes or needs that top line, it is very difficult to be able to deem what is part of the image, and what it not.

Same problem applies for removing the pixels like you asked, an image can have empty pixels in the middle of it…

However this would be the best attempt you could make at the problem

getHeight

local function getHeight( image )
  --# init the image start and end variables, these are what track where the start and end are
  local imgStart = #image --# we need to start at the end so we can apply math.min
  local imgEnd = 0 --# we need to start at the start so we can apply math.max
  --# loop through the table
  for index,imageLine in ipairs(image) do
	--# create a variable to hold if the line has a pixel
	local isLine = false
	--# loop through the pixels in the line
	for i,pixel in ipairs(imageLine) do
	  --# if the pixel is drawable
	  if pixel ~= 0 then
		--# record that there is a pixel, and exit the loop, no need to check anymore, we know there is at least 1
		isLine = true
		break
	  end
	end
	--# if the line has pixels, check if its the start or end
	if isLine then
	  imgStart = math.min(imgStart,index)
	  imgEnd = math.max(imgEnd,index)
	end
  end
  --# return the height of the image, which is the end plus the start, plus 1 because tables start at index 1 not 0
  return imgEnd - imgStart + 1
end

getWidth

function getWidth(img)
  --# the max width
  local maxWidth = 0
  --# loop through the image
  for i,line in pairs(img) do
	--# the variable to hold where the line starts
	local lineStart = #line --# start it at the end so we can apply math.min
	--# the variable to hold where the line ends
	local lineEnd = 0 --# start at the start so we can apply math.max
	--# loop the line
	for index,v in pairs(line) do
	  --# if its a pixel
	  if v ~= 0 then
		--# check if its the start or the end of the line
		lineStart = math.min(lineStart,index)
		lineEnd = math.max(lineEnd,index)
	  end
	end
	--# the length of the line is the end minus the start positions, +1 because tables start at index 1 not 0
	local length = lineEnd - lineStart + 1
	--# check if its the max length
	maxWidth = math.max(maxWidth, length)
  end
  --# return the max length
  return maxWidth
end

So as you can see with the examples above, they both must go and read the information about the pixels and perform some math depending on if its a pixel or not. I chose to show you this method over removing pixels as it was by far the easier method.


EDIT: I pasted the wrong getHeight function from my editor, fixed that

It should be noted that the functions I posted above may not be 100% against missing pixels and such (I didn't test it enough to make sure)

EDIT 2: Fixed a bug that has come about from me always manually reading images, not using paintutils, (was comparing to ' ' not 0) ok its fixed now.
Edited on 23 September 2013 - 11:34 AM
joshmanisdabomb #8
Posted 23 September 2013 - 04:04 PM
Thank you, theoriginalbit. It worked. I've credited you in the project I'm working on.