Provavelmente você está dividindo dois números inteiros e guardando o resultado em um float, por isso p vira 1.0.
Solução: converta qualquer um dos valores da divisão para float utilizando um cast.
float p = (float) img.getHeight() / d.height;
ou
float p = img.getHeight() / (float) d.height;
Explicação:
Existe um conceito chamado de Coerção de tipo em algumas linguages de programação, e é o caso do Java. Nesse caso da divivisão, funciona assim: Quando você utiliza o operador /, basicamente você está chamando uma função para dividir dois números. O compilador infere qual sobrecarga da função você irá utilizar, baseado nos dois argumentos (o número na esquerda e o número na direita).
Se você faz int / int, existe uma função que faz essa divisão. O mesmo ocorre para float / float. Mas e quando misturamos int / float ou float / int? Precisamos ter uma função para cada divisão? E quando entrar long, double, e todos os outros primitivos? E quando a Oracle adicionar mais um tipo primitivo numérico? A quantidade de combinações de sobrecargas necessárias da função de divisão é absurda. Por isso, utiliza-se coerção, que é converter implicitamente de um tipo para outro mais abrangente, sem perda de dados.
Quando utilizamos int / float ou float / int, o int é convertido para float, e então pode-se utilizar a função pronta de float / float. O mesmo acontece para os outros primitivos numéricos (não lembro se char também entra, eu acho que sim).
Nesse teu exemplo, (acredito que) você tá simplesmente dividindo dois ints e guardando-os em um float. A divisão inteira, como diz o próprio nome, não guarda a precisão de ponto flutuante. O resultado da divisão nesse caso é 1.6438356164, porém a divisão inteira trunca o número e retorna 1, int, que é implicitamente castado para float, pois não há perda de precisão de int para float, mais uma coerção.