CGContextDrawImage рисует изображение вверх тормашками при передаче UIImage. CGImage

Если вы посмотрите внимательно, вы увидите, что F_matrix[0] состоит из 8 подмассивов (1-й массив). Следовательно, вы получаете len(F_matrix[0]) как 8. Кроме того, каждый из этих 8 подмассивов содержит 8 элементов, поэтому у вас есть 8x8 = 64 элемента.

Теперь, если вы сделаете

len(F_matrix[0][0])

, вы увидите, что это также приведет к 8. Так как у вас есть 8 подмассивов, у F_matrix[0] будут индексы, работающие от 0 до 7. В частности, каждый из которых будет иметь длину fo 8 как

print (len(F_matrix[0][0])) # 8
print (len(F_matrix[0][1])) # 8
print (len(F_matrix[0][2])) # 8
.
.
.
print (len(F_matrix[0][7])) # 8

РЕДАКТИРОВАТЬ

Чтобы получить общее количество элементов в вашем общем многомерном массиве, сначала необходимо сгладить все измерения до 1-го, а затем рассчитать длину. Итак, для вашего примера, чтобы получить длину (64), вы можете сделать

print (len(F_matrix.flatten()))

len(F_matrix[0]), представляющую длину (размер) первого измерения. Поскольку у вас есть трехмерный массив (1,8,8), длина F_matrix[0] означает, сколько дополнительных элементов (может быть массивом или списком и т. Д.) Содержит. Эти элементы сами по себе могут быть многомерными.

178
задан Suragch 6 March 2016 в 13:05
поделиться

8 ответов

Вместо

CGContextDrawImage(context, CGRectMake(0, 0, 145, 15), image.CGImage);

Использование

[image drawInRect:CGRectMake(0, 0, 145, 15)];

Посреди Вашего начинать/заканчивать CGcontext методы.

Это нарисует изображение с корректной ориентацией в Ваш контекст текущего изображения - я вполне уверен, это имеет некоторое отношение UIImage содержание на знание ориентации, в то время как CGContextDrawImage метод получает базовые необработанные данные изображения без понимания ориентации.

235
ответ дан phimuemue 23 November 2019 в 20:13
поделиться

Я не уверен для UIImage, но этот вид поведения обычно происходит, когда координаты зеркально отражаются. Большинство систем координат OS X возникает в левом нижнем углу, как в Постскриптуме и PDF. Но CGImage система координат возникает в левом верхнем углу.

Возможные решения могут включить isFlipped свойство или scaleYBy:-1 аффинное преобразование.

7
ответ дан mouviciel 23 November 2019 в 20:13
поделиться

Даже после применения всего я упомянул, у меня все еще были драмы с изображениями. В конце я только что использовал Калеку для создания 'зеркально отраженной вертикальной' версии всех моих изображений. Теперь я не должен использовать никого, Преобразовывает. Надо надеяться, это не вызовет дальнейшие проблемы вниз дорожка.

кто-либо знает, почему CGContextDrawImage нарисовал бы мое изображение вверх тормашками? Я загружаю изображение в из моего приложения:

Quartz2d использует другую систему координат, где источник находится в левом нижнем углу. Таким образом, когда Кварц тянет пиксель x [5], y[10] 100 * 100 изображений, тот пиксель оттягивается в левом нижнем углу вместо верхнего левого угла. Таким образом вызывая 'зеркально отраженное' изображение.

x соответствия системы координат, таким образом, необходимо будет зеркально отразить координаты y.

CGContextTranslateCTM(context, 0, image.size.height);

Это означает, что мы перевели изображение 0 единицами на оси X и высотой изображений на оси y. Однако это одно будет означать, что наше изображение все еще вверх тормашками, просто оттягивает "image.size.height" ниже, где мы хотим, чтобы это было оттянуто.

руководство по программированию Quartz2D рекомендует использовать ScaleCTM и передать отрицательные величины для зеркального отражения изображения. Можно использовать следующий код, чтобы сделать это -

CGContextScaleCTM(context, 1.0, -1.0);

Объединение два незадолго до Вашего CGContextDrawImage вызов, и необходимо нарисовать изображение правильно.

UIImage *image = [UIImage imageNamed:@"testImage.png"];    
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);       

CGContextTranslateCTM(context, 0, image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGContextDrawImage(context, imageRect, image.CGImage);

Просто быть осторожным, если Ваши координаты imageRect не соответствуют тем из Вашего изображения, поскольку можно получить непреднамеренные результаты.

Для преобразования назад координат:

CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0, -imageRect.size.height);
213
ответ дан pravdomil 23 November 2019 в 20:13
поделиться

Это происходит, потому что QuartzCore имеет систему координат "нижняя левая часть", в то время как UIKit †“, "верхний левый".

В случае можно расшириться CGContext:

extension CGContext {
  func changeToTopLeftCoordinateSystem() {
    translateBy(x: 0, y: boundingBoxOfClipPath.size.height)
    scaleBy(x: 1, y: -1)
  }
}

// somewhere in render 
ctx.saveGState()
ctx.changeToTopLeftCoordinateSystem()
ctx.draw(cgImage!, in: frame)
0
ответ дан 23 November 2019 в 20:13
поделиться

ответ Swift 5 на основе превосходного ответа @ZpaceZombor

, Если у Вас есть UIImage, просто используйте

var image: UIImage = .... 
image.draw(in: CGRect)

, Если у Вас есть использование CGImage моя категория ниже

Примечание: В отличие от некоторых других ответов, этот принимает во внимание, что реагирование Вас хочет подойти к концу, мог бы иметь y! = 0. Те ответы, которые не принимают во внимание, которые являются неправильными и не будут работать в общем случае.

extension CGContext {
    final func drawImage(image: CGImage, inRect rect: CGRect) {

        //flip coords
        let ty: CGFloat = (rect.origin.y + rect.size.height)
        translateBy(x: 0, y: ty)
        scaleBy(x: 1.0, y: -1.0)

        //draw image
        let rect__y_zero = CGRect(x: rect.origin.x, y: 0, width: rect.width, height: rect.height)
        draw(image, in: rect__y_zero)

        //flip back
        scaleBy(x: 1.0, y: -1.0)
        translateBy(x: 0, y: -ty)

    }
} 

Использование как это:

let imageFrame: CGRect = ...
let context: CGContext = ....
let img: CGImage = ..... 
context.drawImage(image: img, inRect: imageFrame)
0
ответ дан 23 November 2019 в 20:13
поделиться

Я использую этот Swift 5, чистый Базовая Графика расширение, которое правильно обрабатывает ненулевые источники в изображении, реагирует:

extension CGContext {

    /// Draw `image` flipped vertically, positioned and scaled inside `rect`.
    public func drawFlipped(_ image: CGImage, in rect: CGRect) {
        self.saveGState()
        self.translateBy(x: 0, y: rect.origin.y + rect.height)
        self.scaleBy(x: 1.0, y: -1.0)
        self.draw(image, in: CGRect(origin: CGPoint(x: rect.origin.x, y: 0), size: rect.size))
        self.restoreGState()
    }
}

можно использовать его точно как CGContext регулярный draw(: in:) метод:

ctx.drawFlipped(myImage, in: myRect)
0
ответ дан 23 November 2019 в 20:13
поделиться

drawInRect - это, конечно, то, что нужно. Вот еще одна маленькая деталь, которая может пригодиться при выполнении этого действия. Обычно рисунок и прямоугольник, в который он будет помещен, не совпадают. В этом случае drawInRect растянет картинку. Вот быстрый и классный способ убедиться, что соотношение сторон картинки не изменится, путем обратного преобразования (которое должно вместить все изображение):

//Picture and irect don't conform, so there'll be stretching, compensate
    float xf = Picture.size.width/irect.size.width;
    float yf = Picture.size.height/irect.size.height;
    float m = MIN(xf, yf);
    xf /= m;
    yf /= m;
    CGContextScaleCTM(ctx, xf, yf);

    [Picture drawInRect: irect];
1
ответ дан 23 November 2019 в 20:13
поделиться

UIImage содержит CGImage в качестве основного элемента содержимого а также коэффициенты масштабирования и ориентации. Поскольку CGImage и его различные функции унаследованы от OSX, он предполагает перевернутую систему координат по сравнению с iPhone. Когда вы создаете UIImage , для компенсации по умолчанию используется перевернутая ориентация (вы можете это изменить!). Использовать . Свойство CGImage для доступа к очень мощным функциям CGImage , но рисование на экране iPhone и т. Д. Лучше всего выполнять с помощью методов UIImage .

3
ответ дан 23 November 2019 в 20:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: