저는 석영 2D 및 목표 C를 사용하여 바느질 패턴을 PDF 파일로 출력하는 프로그램을 작성하고 있습니다. 파이썬에서 코딩 된 다른 프로그램을 사용하여 포스트 스크립트 파일을 출력합니다. 미리보기에서 열면 PDF로 변환됩니다. 두 번째 응용 프로그램은 오픈 소스이기 때문에 필자는 PDF 레이아웃에 사용하는 설정, 특히 사각형 사이의 갭 크기와 크기가 동일한 지 확인했습니다.포스트 스크립트 대 석영 2D에서 생성 된 PDF
아래 이미지에서 다른 프로그램의 출력은 왼쪽에 있고 광산은 오른쪽에 있고 둘 다 실제 크기입니다. 내가 겪고있는 문제는 실제 크기에서 출력물의 갭 라인이 간헐적 인 반면, 다른 한편으로는 모든 갭을 볼 수 있다는 것입니다. 누구든지 포스트 스크립트 파일과의 렌더링 차이에 대해 알고 있다면 궁금합니다. 내 출력을 확대 할 수 있으며 틈이 나타나지만 왜 이런 차이가 있는지 이해할 수 없습니다.
정사각형은 8 픽셀 너비와 높이가되도록 설정되어 있으며 두 응용 프로그램에서 간격이 1 픽셀 씩 간격이 2 픽셀 씩 10 개마다 정해지며 광산에서는 에일리어싱을 사용하지 않도록 설정됩니다. 필자는 CGPDFContext로 직접 드로잉을 시도하고 CGLayerRef로 드로잉하여 레이어를 PDF 컨텍스트로 드로잉 해 보았습니다. 그러나 동일한 결과를 얻었습니다. 레이아웃 배치에 정수 값을 사용하고 있으며 픽셀 위치의 일부에 사각형을 배치하는 것을 피했습니다.
또한 출력을 CGBitmapContext로 그려 넣고 결과 비트 맵을 PDF 컨텍스트로 그려 보았습니다. 그러나 확대 된 래스터이므로 끔찍한 결과가 나타납니다.
필자가 지적한 마지막 차이점은 포스트 스크립트에서 생성 된 PDF의 파일 크기가 제작 한 파일 크기보다 훨씬 작으며 그림 그리기 이후부터 그려야 할 경로와 관련이 있다고 생각합니다. PDF 컨텍스트는 그림을 파일에 기록 된 일련의 PDF 드로잉 명령으로 기록합니다. 이미지를 표시하는 것과 비교하면 상당히 많은 공간이 필요합니다.
필자는 아래 코드를 작성하여 도움이 될만한 코드를 포함 시켰지만, 포스트 스크립트와 Quartz 사이에 렌더링 차이가 있는지 궁금해하고 있습니다. 이러한 차이점을 설명 할 수 있고 내 출력이 일치하도록하십시오.
이 (업 로더 내가 이미지를 게시하려면 적어도 10 평판 필요하지만, 내가 다시이 링크 http://i.stack.imgur.com/nr588.jpg을 말한다 포스트 스크립트 출력은 왼쪽에, 내 석영 출력이 오른쪽에 내 출력에, 눈금 선은 간헐적)-(void)makePDF:(NSImage*)image withPixelArray:(unsigned char *)rawData{
NSString *currentUserHomeDirectory = NSHomeDirectory();
currentUserHomeDirectory = [currentUserHomeDirectory stringByAppendingString:@"/Desktop/"];
currentUserHomeDirectory = [currentUserHomeDirectory stringByAppendingString:[image name]];
currentUserHomeDirectory = [currentUserHomeDirectory stringByAppendingPathExtension:@"pdf"];
CGContextRef pdfContext;
CFStringRef path;
CFURLRef url;
int width = 792;
int height = 612;
CFMutableDictionaryRef myDictionary = NULL;
CFMutableDictionaryRef pageDictionary = NULL;
const char *filename = [currentUserHomeDirectory UTF8String];
path = CFStringCreateWithCString (NULL, filename,
kCFStringEncodingUTF8);
url = CFURLCreateWithFileSystemPath (NULL, path,
kCFURLPOSIXPathStyle, 0);
CFRelease (path);
myDictionary = CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CGRect pageRect = CGRectMake(0, 0, width, height);
pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary);
const CGFloat whitePoint[3]= {0.95047, 1.0, 1.08883};
const CGFloat blackPoint[3]={0,0,0};
const CGFloat gammavalues[3] = {2.2,2.2,2.2};
const CGFloat matrix[9] = {0.4124564, 0.3575761, 0.1804375, 0.2126729, 0.7151522, 0.072175, 0.0193339, 0.119192, 0.9503041};
CGColorSpaceRef myColorSpace = CGColorSpaceCreateCalibratedRGB(&whitePoint[3], &blackPoint[3], &gammavalues[3], &matrix[9]);
CGContextSetFillColorSpace (
pdfContext,
myColorSpace
);
int annotationNumber =0;
int match=0;
CFRelease(myDictionary);
CFRelease(url);
pageDictionary = CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDataRef boxData = CFDataCreate(NULL,(const UInt8 *)&pageRect, sizeof (CGRect));
CFDictionarySetValue(pageDictionary, kCGPDFContextMediaBox, boxData);
int m = 0;
int sidestep = 0;
int downstep = 0;
int maxc = 0;
int maxr = 0;
int columnsPerPage = 70;
int rowsPerPage = 60;
int symbolSize = 8;
int gapSize=1;
CGContextSetShouldAntialias(pdfContext, NO);
int pages = ceil([image size].width/columnsPerPage) * ceil([image size].height/rowsPerPage);
for (int g=0; g<pages; g++) {
int offsetX = 32;
int offsetY = 32;
if (sidestep == ceil([image size].width/columnsPerPage)-1) {
maxc=[image size].width-sidestep*columnsPerPage;
}else {
maxc=columnsPerPage;
}
if (downstep == ceil([image size].height/rowsPerPage)-1) {
maxr=[image size].height-downstep*rowsPerPage;
}else {
maxr=rowsPerPage;
}
CGPDFContextBeginPage (pdfContext, pageDictionary);
CGContextTranslateCTM(pdfContext, 0.0, 612);
CGContextScaleCTM(pdfContext, 1.0, -1.0);
CGContextSetShouldAntialias(pdfContext, NO);
int r=0;
while (r<maxr){
int c=0;
while (c<maxc){
m = sidestep*columnsPerPage+c+downstep*[image size].width*rowsPerPage+r*[image size].width;
//Reset offsetX
if (c==0) {
offsetX=32;
}
//Increase offset for gridlines
if (c==0 && r%10==0&&r!=0) {
offsetY+=2;
}
if (c%10==0&&c!=0) {
offsetX+=2;
}
//DRAW SQUARES
CGContextSetRGBFillColor (pdfContext, (double)rawData[m*4]/255.,(double) rawData[m*4+1]/255., (double)rawData[m*4+2]/255., 1);
CGContextFillRect (pdfContext, CGRectMake (c*(symbolSize+gapSize)+offsetX, r*(symbolSize+gapSize)+offsetY, symbolSize, symbolSize));
if ([usedColorsPaths count]!=0) {
for (int z=0; z<[usedColorsPaths count]; z++) {
if ([[[usedColorsPaths allKeys] objectAtIndex:z] isEqualToString:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4], rawData[m*4+1], rawData[m*4+2]]]) {
match=1;
if (rawData[m*4+3] == 0) {
CGContextDrawLayerAtPoint (pdfContext, CGPointMake(c*(symbolSize+1)+offsetX-2, r*(symbolSize+1)+offsetY-2), [Anotations colorAnnotations:pdfContext :[[usedColorsPaths objectForKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4],rawData[m*4+1],rawData[m*4+2]]]intValue] :symbolSize+4 :0]);
}
else{
CGContextDrawLayerAtPoint (pdfContext, CGPointMake(c*(symbolSize+1)+offsetX, r*(symbolSize+1)+offsetY),[Anotations colorAnnotations:pdfContext :[[usedColorsPaths objectForKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4], rawData[m*4+1], rawData[m*4+2]]] intValue] :symbolSize :0]);
}
break;
}
}
if (match==0) {
if (rawData[m*4+3] == 0) {
[usedColorsPaths setObject:[NSNumber numberWithInt:455] forKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4], rawData[m*4+1], rawData[m*4+2]]];
CGContextDrawLayerAtPoint (pdfContext, CGPointMake(c*(symbolSize+1)+offsetX-2, r*(symbolSize+1)+offsetY-2), [Anotations colorAnnotations:pdfContext :[[usedColorsPaths objectForKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4],rawData[m*4+1],rawData[m*4+2]]]intValue] :symbolSize+4 :0]);
}
else{
[usedColorsPaths setObject:[NSNumber numberWithInt:annotationNumber] forKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4], rawData[m*4+1], rawData[m*4+2]]];
CGContextDrawLayerAtPoint (pdfContext, CGPointMake(c*(symbolSize+1)+offsetX, r*(symbolSize+1)+offsetY), [Anotations colorAnnotations:pdfContext :[[usedColorsPaths objectForKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4],rawData[m*4+1],rawData[m*4+2]]]intValue] :symbolSize :0]);
}
annotationNumber++;
if (annotationNumber==9) {
annotationNumber=0;
}
}
match=0;
}
if ([usedColorsPaths count]==0) {
if (rawData[m*4+3] == 0) {
[usedColorsPaths setObject:[NSNumber numberWithInt:455] forKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4], rawData[m*4+1], rawData[m*4+2]]];
CGContextDrawLayerAtPoint (pdfContext, CGPointMake(c*(symbolSize+1)+offsetX-2, r*(symbolSize+1)+offsetY-2), [Anotations colorAnnotations:pdfContext :[[usedColorsPaths objectForKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4],rawData[m*4+1],rawData[m*4+2]]]intValue] :symbolSize+4 :0]);
}
else{
[usedColorsPaths setObject:[NSNumber numberWithInt:annotationNumber] forKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4], rawData[m*4+1], rawData[m*4+2]]];
CGContextDrawLayerAtPoint (pdfContext, CGPointMake(c*(symbolSize+1)+offsetX, r*(symbolSize+1)+offsetY), [Anotations colorAnnotations:pdfContext :[[usedColorsPaths objectForKey:[NSString stringWithFormat:@"%i,%i,%i",rawData[m*4],rawData[m*4+1],rawData[m*4+2]]]intValue] :symbolSize :0]);
}
annotationNumber++;
}
c++;
}
r++;
}
sidestep++;
if (sidestep == ceil([image size].width/columnsPerPage)) {
sidestep=0;
downstep+=1;
}
CGContextSaveGState(pdfContext);
CGPDFContextEndPage (pdfContext);
}
CGContextRelease(pdfContext);
CFRelease(pageDictionary);
CFRelease(boxData);}
답장을 보내 주셔서 감사합니다. 어도비 일러스트 레이터에서 약간의 작업을하므로 픽셀이 아닌 점을 사용하여 벡터가 만들어지는 방법을 얻지 만 PDF 컨텍스트를 만들 때 점의 페이지 크기를 나타내는 직사각형을 제공 한 다음 해당 컨텍스트에 그려야합니다. , 그릴 곳을 지정합니다. 나는 그들이 픽셀을 부름으로써 용어를 잘못 사용했다고 생각해. 미안. 저에게 PDF 예제를 공유 할 수있는 방법이 있다면 기꺼이 하겠지만 제가 제공 한 이미지는 예제의 직접적인 스크린 샷입니다. PDF로 그림을 그리는 것이 중독과 중독 사이의 공간을 보여주는 데 어려움을 겪고 있습니다. – nintandrew
파일을 보관 용 계정에 집어 넣고 여기에 URL을 공유 하시겠습니까?사용하는 좌표는 실수가 아니고 정수가되어야하며 그렇게하면 제대로 작동해야합니다 (물론 Mac 프로그래머가 아니기 때문에 Quartz에 대해 전혀 알지 못합니다). Quartz가 당신을 정수 좌표로 제한한다고 생각할 수도 있지만, 그것은 거의 불가능할 것 같다. 단순히 실제 값을 대신 사용해 보았습니까? 아, 또한 확대 할 때 예상되는 틈이 나타나면 그 틈이 1 픽셀 너비보다 훨씬 작은 지점까지 출력을 확대하여 발생하는 뷰어의 인위적인 결과입니다. – KenS
도움을 주셔서 감사합니다. 그러나 이것이 안티 앨리어싱 문제였습니다. 앤티 앨리어싱이 없으면 확대 된 뷰에서 프로그램에 단일 포인트 간격을 렌더링하는 데 문제가있었습니다. 수정 사항은 앤티 엘리 어싱을 다시 켜는 것이었고 결과물은 매력처럼 작동합니다. 이 문제를 조사 할 시간을내어 주셔서 감사합니다. 간과 한 것 같은 간단한 일이었습니다. – nintandrew