// // ImageUtils.m // RNBluetoothEscposPrinter // // Created by januslo on 2018/10/7. // Copyright © 2018年 Facebook. All rights reserved. // #import #import #import "ImageUtils.h" @implementation ImageUtils : NSObject int p0[] = { 0, 0x80 }; int p1[] = { 0, 0x40 }; int p2[] = { 0, 0x20 }; int p3[] = { 0, 0x10 }; int p4[] = { 0, 0x08 }; int p5[] = { 0, 0x04 }; int p6[] = { 0, 0x02 }; + (UIImage*)imagePadLeft:(NSInteger) left withSource: (UIImage*)source { CGSize orgSize = [source size]; CGSize size = CGSizeMake(orgSize.width + [[NSNumber numberWithInteger: left] floatValue], orgSize.height); UIGraphicsBeginImageContext(size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]); CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); [source drawInRect:CGRectMake(left, 0, orgSize.width, orgSize.height) blendMode:kCGBlendModeNormal alpha:1.0]; UIImage *paddedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return paddedImage; } +(uint8_t *)imageToGreyImage:(UIImage *)image { // Create image rectangle with current image width/height int kRed = 1; int kGreen = 2; int kBlue = 4; int colors = kGreen | kBlue | kRed; CGFloat actualWidth = image.size.width; CGFloat actualHeight = image.size.height; NSLog(@"actual size: %f,%f",actualWidth,actualHeight); uint32_t *rgbImage = (uint32_t *) malloc(actualWidth * actualHeight * sizeof(uint32_t)); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(rgbImage, actualWidth, actualHeight, 8, actualWidth*4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast); CGContextSetInterpolationQuality(context, kCGInterpolationHigh); CGContextSetShouldAntialias(context, NO); CGContextDrawImage(context, CGRectMake(0, 0, actualWidth, actualHeight), [image CGImage]); CGContextRelease(context); CGColorSpaceRelease(colorSpace); // CGRect imageRect = CGRectMake(0, 0, actualWidth, actualHeight); // CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); // // CGContextRef context = CGBitmapContextCreate(rgbImage, actualWidth, actualHeight, 8, actualWidth*4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast); // CGContextDrawImage(context, imageRect, [image CGImage]); // // //CGImageRef grayImage = CGBitmapContextCreateImage(context); // CGColorSpaceRelease(colorSpace); // CGContextRelease(context); // context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, nil, kCGImageAlphaOnly); // CGContextDrawImage(context, imageRect, [image CGImage]); // CGImageRef mask = CGBitmapContextCreateImage(context); // CGContextRelease(context); // UIImage *grayScaleImage = [UIImage imageWithCGImage:CGImageCreateWithMask(grayImage, mask) scale:image.scale orientation:image.imageOrientation]; // CGImageRelease(grayImage); // CGImageRelease(mask); // Return the new grayscale image //now convert to grayscale uint8_t *m_imageData = (uint8_t *) malloc(actualWidth * actualHeight); // NSMutableString *toLog = [[NSMutableString alloc] init]; for(int y = 0; y < actualHeight; y++) { for(int x = 0; x < actualWidth; x++) { uint32_t rgbPixel=rgbImage[(int)(y*actualWidth+x)]; uint32_t sum=0,count=0; if (colors & kRed) {sum += (rgbPixel>>24)&255; count++;} if (colors & kGreen) {sum += (rgbPixel>>16)&255; count++;} if (colors & kBlue) {sum += (rgbPixel>>8)&255; count++;} // [toLog appendFormat:@"pixel:%d,sum:%d,count:%d,val:%d;",rgbPixel,sum,count,(int)(sum/count)]; m_imageData[(int)(y*actualWidth+x)]=sum/count; } } //NSLog(@"m_imageData:%@",toLog); return m_imageData; // // Create image rectangle with current image width/height // CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height); // // // Grayscale color space // CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); // // // Create bitmap content with current image size and grayscale colorspace // CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone); // // // Draw image into current context, with specified rectangle // // using previously defined context (with grayscale colorspace) // CGContextDrawImage(context, imageRect, [image CGImage]); // // // Create bitmap image info from pixel data in current context // CGImageRef imageRef = CGBitmapContextCreateImage(context); // // // Create a new UIImage object // UIImage *newImage = [UIImage imageWithCGImage:imageRef]; // // // Release colorspace, context and bitmap information // CGColorSpaceRelease(colorSpace); // CGContextRelease(context); // CFRelease(imageRef); // // // Return the new grayscale image // return newImage; } + (UIImage *)imageWithImage:(UIImage *)image scaledToFillSize:(CGSize)size { CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height); CGFloat width = image.size.width * scale; CGFloat height = image.size.height * scale; CGRect imageRect = CGRectMake((size.width - width)/2.0f, (size.height - height)/2.0f, width, height); UIGraphicsBeginImageContextWithOptions(size, NO, 0); [image drawInRect:imageRect]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } + (NSData*)bitmapToArray:(UIImage*) bmp { CGDataProviderRef provider = CGImageGetDataProvider(bmp.CGImage); NSData* data = (id)CFBridgingRelease(CGDataProviderCopyData(provider)); return data; } /** **Raster Image - $1D $76 $30 m xL xH yL yH d1...dk Prints a raster image Format: Hex $1D $76 30 m xL xH yL yH d1...dk ASCII GS v % m xL xH yL yH d1...dk Decimal 29 118 48 m xL xH yL yH d1...dk Notes: When ​standard mode​ is enabled, this command is only executed when there is no data in the print buffer. (Line is empty) The defined data (​d​) defines each byte of the raster image. Each bit in every byte defines a pixel. A bit set to 1 is printed and a bit set to 0 is not printed. If a raster bit image exceeds one line, the excess data is not printed. This command feeds as much paper as is required to print the entire raster bit image, regardless of line spacing defined by 1/6” or 1/8” commands. After the raster bit image is printed, the print position goes to the beginning of the line. The following commands have no effect on a raster bit image: Emphasized Double Strike Underline White/Black Inverse Printing Upside-Down Printing Rotation Left margin Print Area Width A raster bit image data is printed in the following order: d1 d2 … dx dx + 1 dx + 2 … dx * 2 . . . . … dk - 2 dk - 1 dk Defines and prints a raster bit image using the mode specified by ​m​: m Mode Width Scalar Heigh Scalar 0, 48 Normal x1 x1 1, 49 Double Width x2 x1 2, 50 Double Height x1 x2 3, 51 Double Width/Height x2 x2 xL, xH ​defines the raster bit image in the horizontal direction in ​bytes​ using two-byte number definitions. (​xL + (xH * 256)) Bytes yL, yH ​defines the raster bit image in the vertical direction in ​dots​ using two-byte number definitions. (​yL + (yH * 256)) Dots d ​ specifies the bit image data in raster format. k ​indicates the number of bytes in the bit image. ​k ​is not transmitted and is there for explanation only. **/ + (NSData *)eachLinePixToCmd:(unsigned char *)src nWidth:(NSInteger) nWidth nHeight:(NSInteger) nHeight nMode:(NSInteger) nMode { NSLog(@"SIZE OF SRC: %lu",sizeof(&src)); NSInteger nBytesPerLine = (int)nWidth/8; unsigned char * data = malloc(nHeight*(8+nBytesPerLine)); // const char* srcData = (const char*)[src bytes]; NSInteger k = 0; // NSMutableString *toLog = [[NSMutableString alloc] init]; for(int i=0;i grayave) { despixels[k] = 0; } else { despixels[k] = 1; // oneCount++; } ++k; // [logStr appendFormat:@"%d,",despixels[k]]; } } // NSLog(@"despixels [with 1 count:%d]: %@",oneCount,logStr); return despixels; } +(NSData *)pixToTscCmd:(uint8_t *)src width:(NSInteger) width { int length = (int)width/8; uint8_t * data = malloc(length); int k = 0; for(int j = 0;k