Во встроенном приложении C у меня есть большое изображение, которое я хотел бы повернуть на 90 градусов. В настоящее время я использую известный простой алгоритм, чтобы сделать это. Однако этот алгоритм требует, чтобы я сделал другую копию изображения. Я хотел бы постараться не выделять память для копии, я скорее поверну ее оперативный. Так как изображение не является квадратным, это хитро. Кто-либо знает о подходящем алгоритме?
Отредактированный для добавления разъяснения, потому что люди спрашивают:
Я храню изображение в обычном формате:
// Images are 16 bpp
struct Image {
int width;
int height;
uint16_t * data;
};
uint16_t getPixel(Image *img, int x, int y)
{
return img->data[y * img->width + x];
}
Я надеюсь переместить содержание data
массив вокруг, затем подкачайте по width
и height
членские переменные. Таким образом, если я запущу с изображения на 9x20 пикселей, затем поверну его, то я закончу с изображением на 20x9 пикселей. Это изменяет шаг изображения, которое усложняет алгоритм много.
Это может помочь: In-place matrix transposition.
(Возможно, вам также придется сделать некоторое зеркальное отражение после транспонирования, как упоминает rlbond).
Если вы читаете изображение из памяти в «неправильном порядке», это по сути то же самое, что вращать его. Это может или не может подходить для того, что вы делаете, но вот:
image[y][x] /* assuming this is the original orientation */
image[x][original_width - y] /* rotated 90 degrees ccw */
image[original_height - x][y] /* 90 degrees cw */
image[original_height - y][original_width - x] /* 180 degrees */
Это может быть слишком расплывчатым и не тем, что вы ищете, но я все равно опубликую.
Если вы считаете изображение двумерным массивом пикселей, вам нужно только изменить порядок верхнего уровня или вложенного массива, в зависимости от того, хотите ли вы зеркальное отображение по горизонтали или по вертикали.
Итак, вы должны либо пройти через каждый столбец пикселей (0-> columns / 2) и поменять местами их (так что вам нужна только временная память для 1 пикселя, а не всего изображения), либо прокручивать строки для горизонтального переворачивания .. Имеет ли это смысл? Если нет, разработаю / напишу код ..
Не уверен, какую обработку вы будете делать после поворота, но вы можете оставить это в покое и использовать другую функцию для чтения повернутого пикселя из исходной памяти.
uint16_t getPixel90(Image *img, int x, int y)
{
return img->data[(img->height - x) * img->width + y];
}
Где входные параметры x и y поменялись размерностью с исходной