Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

ImageUtils.m 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. //
  2. // ImageUtils.m
  3. // RNBluetoothEscposPrinter
  4. //
  5. // Created by januslo on 2018/10/7.
  6. // Copyright © 2018年 Facebook. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import <UIKit/UIKit.h>
  10. #import "ImageUtils.h"
  11. @implementation ImageUtils : NSObject
  12. int p0[] = { 0, 0x80 };
  13. int p1[] = { 0, 0x40 };
  14. int p2[] = { 0, 0x20 };
  15. int p3[] = { 0, 0x10 };
  16. int p4[] = { 0, 0x08 };
  17. int p5[] = { 0, 0x04 };
  18. int p6[] = { 0, 0x02 };
  19. + (UIImage*)imagePadLeft:(NSInteger) left withSource: (UIImage*)source
  20. {
  21. CGSize orgSize = [source size];
  22. CGSize size = CGSizeMake(orgSize.width + [[NSNumber numberWithInteger: left] floatValue], orgSize.height);
  23. UIGraphicsBeginImageContext(size);
  24. CGContextRef context = UIGraphicsGetCurrentContext();
  25. CGContextSetFillColorWithColor(context,
  26. [[UIColor whiteColor] CGColor]);
  27. CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));
  28. [source drawInRect:CGRectMake(left, 0, orgSize.width, orgSize.height)
  29. blendMode:kCGBlendModeNormal alpha:1.0];
  30. UIImage *paddedImage = UIGraphicsGetImageFromCurrentImageContext();
  31. UIGraphicsEndImageContext();
  32. return paddedImage;
  33. }
  34. +(uint8_t *)imageToGreyImage:(UIImage *)image {
  35. // Create image rectangle with current image width/height
  36. int kRed = 1;
  37. int kGreen = 2;
  38. int kBlue = 4;
  39. int colors = kGreen | kBlue | kRed;
  40. CGFloat actualWidth = image.size.width;
  41. CGFloat actualHeight = image.size.height;
  42. NSLog(@"actual size: %f,%f",actualWidth,actualHeight);
  43. uint32_t *rgbImage = (uint32_t *) malloc(actualWidth * actualHeight * sizeof(uint32_t));
  44. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  45. CGContextRef context = CGBitmapContextCreate(rgbImage, actualWidth, actualHeight, 8, actualWidth*4, colorSpace,
  46. kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
  47. CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
  48. CGContextSetShouldAntialias(context, NO);
  49. CGContextDrawImage(context, CGRectMake(0, 0, actualWidth, actualHeight), [image CGImage]);
  50. CGContextRelease(context);
  51. CGColorSpaceRelease(colorSpace);
  52. // CGRect imageRect = CGRectMake(0, 0, actualWidth, actualHeight);
  53. // CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
  54. //
  55. // CGContextRef context = CGBitmapContextCreate(rgbImage, actualWidth, actualHeight, 8, actualWidth*4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
  56. // CGContextDrawImage(context, imageRect, [image CGImage]);
  57. //
  58. // //CGImageRef grayImage = CGBitmapContextCreateImage(context);
  59. // CGColorSpaceRelease(colorSpace);
  60. // CGContextRelease(context);
  61. // context = CGBitmapContextCreate(nil, actualWidth, actualHeight, 8, 0, nil, kCGImageAlphaOnly);
  62. // CGContextDrawImage(context, imageRect, [image CGImage]);
  63. // CGImageRef mask = CGBitmapContextCreateImage(context);
  64. // CGContextRelease(context);
  65. // UIImage *grayScaleImage = [UIImage imageWithCGImage:CGImageCreateWithMask(grayImage, mask) scale:image.scale orientation:image.imageOrientation];
  66. // CGImageRelease(grayImage);
  67. // CGImageRelease(mask);
  68. // Return the new grayscale image
  69. //now convert to grayscale
  70. uint8_t *m_imageData = (uint8_t *) malloc(actualWidth * actualHeight);
  71. // NSMutableString *toLog = [[NSMutableString alloc] init];
  72. for(int y = 0; y < actualHeight; y++) {
  73. for(int x = 0; x < actualWidth; x++) {
  74. uint32_t rgbPixel=rgbImage[(int)(y*actualWidth+x)];
  75. uint32_t sum=0,count=0;
  76. if (colors & kRed) {sum += (rgbPixel>>24)&255; count++;}
  77. if (colors & kGreen) {sum += (rgbPixel>>16)&255; count++;}
  78. if (colors & kBlue) {sum += (rgbPixel>>8)&255; count++;}
  79. // [toLog appendFormat:@"pixel:%d,sum:%d,count:%d,val:%d;",rgbPixel,sum,count,(int)(sum/count)];
  80. m_imageData[(int)(y*actualWidth+x)]=sum/count;
  81. }
  82. }
  83. //NSLog(@"m_imageData:%@",toLog);
  84. return m_imageData;
  85. // // Create image rectangle with current image width/height
  86. // CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
  87. //
  88. // // Grayscale color space
  89. // CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
  90. //
  91. // // Create bitmap content with current image size and grayscale colorspace
  92. // CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);
  93. //
  94. // // Draw image into current context, with specified rectangle
  95. // // using previously defined context (with grayscale colorspace)
  96. // CGContextDrawImage(context, imageRect, [image CGImage]);
  97. //
  98. // // Create bitmap image info from pixel data in current context
  99. // CGImageRef imageRef = CGBitmapContextCreateImage(context);
  100. //
  101. // // Create a new UIImage object
  102. // UIImage *newImage = [UIImage imageWithCGImage:imageRef];
  103. //
  104. // // Release colorspace, context and bitmap information
  105. // CGColorSpaceRelease(colorSpace);
  106. // CGContextRelease(context);
  107. // CFRelease(imageRef);
  108. //
  109. // // Return the new grayscale image
  110. // return newImage;
  111. }
  112. + (UIImage *)imageWithImage:(UIImage *)image scaledToFillSize:(CGSize)size
  113. {
  114. CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height);
  115. CGFloat width = image.size.width * scale;
  116. CGFloat height = image.size.height * scale;
  117. CGRect imageRect = CGRectMake((size.width - width)/2.0f,
  118. (size.height - height)/2.0f,
  119. width,
  120. height);
  121. UIGraphicsBeginImageContextWithOptions(size, NO, 0);
  122. [image drawInRect:imageRect];
  123. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  124. UIGraphicsEndImageContext();
  125. return newImage;
  126. }
  127. + (NSData*)bitmapToArray:(UIImage*) bmp
  128. {
  129. CGDataProviderRef provider = CGImageGetDataProvider(bmp.CGImage);
  130. NSData* data = (id)CFBridgingRelease(CGDataProviderCopyData(provider));
  131. return data;
  132. }
  133. /**
  134. **Raster Image - $1D $76 $30 m xL xH yL yH d1...dk
  135. Prints a raster image
  136. Format:
  137. Hex $1D $76 30 m xL xH yL yH d1...dk
  138. ASCII GS v % m xL xH yL yH d1...dk
  139. Decimal 29 118 48 m xL xH yL yH d1...dk
  140. Notes:
  141. When ​standard mode​ is enabled, this command is only executed when there is no data in the print buffer. (Line is empty)
  142. 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.
  143. If a raster bit image exceeds one line, the excess data is not printed.
  144. 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.
  145. After the raster bit image is printed, the print position goes to the beginning of the line.
  146. The following commands have no effect on a raster bit image:
  147. Emphasized
  148. Double Strike
  149. Underline
  150. White/Black Inverse Printing
  151. Upside-Down Printing
  152. Rotation
  153. Left margin
  154. Print Area Width
  155. A raster bit image data is printed in the following order:
  156. d1 d2 … dx
  157. dx + 1 dx + 2 … dx * 2
  158. . . . .
  159. … dk - 2 dk - 1 dk
  160. Defines and prints a raster bit image using the mode specified by ​m​:
  161. m Mode Width Scalar Heigh Scalar
  162. 0, 48 Normal x1 x1
  163. 1, 49 Double Width x2 x1
  164. 2, 50 Double Height x1 x2
  165. 3, 51 Double Width/Height x2 x2
  166. xL, xH ​defines the raster bit image in the horizontal direction in ​bytes​ using two-byte number definitions. (​xL + (xH * 256)) Bytes
  167. yL, yH ​defines the raster bit image in the vertical direction in ​dots​ using two-byte number definitions. (​yL + (yH * 256)) Dots
  168. d ​ specifies the bit image data in raster format.
  169. k ​indicates the number of bytes in the bit image. ​k ​is not transmitted and is there for explanation only.
  170. **/
  171. + (NSData *)eachLinePixToCmd:(unsigned char *)src nWidth:(NSInteger) nWidth nHeight:(NSInteger) nHeight nMode:(NSInteger) nMode
  172. {
  173. NSLog(@"SIZE OF SRC: %lu",sizeof(&src));
  174. NSInteger nBytesPerLine = (int)nWidth/8;
  175. unsigned char * data = malloc(nHeight*(8+nBytesPerLine));
  176. // const char* srcData = (const char*)[src bytes];
  177. NSInteger k = 0;
  178. // NSMutableString *toLog = [[NSMutableString alloc] init];
  179. for(int i=0;i<nHeight;i++){
  180. NSInteger var10 = i*(8+nBytesPerLine);
  181. //GS v 0 m xL xH yL yH d1....dk 打印光栅位图
  182. data[var10 + 0] = 29;//GS
  183. data[var10 + 1] = 118;//v
  184. data[var10 + 2] = 48;//0
  185. data[var10 + 3] = (unsigned char)(nMode & 1);
  186. data[var10 + 4] = (unsigned char)(nBytesPerLine % 256);//xL
  187. data[var10 + 5] = (unsigned char)(nBytesPerLine / 256);//xH
  188. data[var10 + 6] = 1;//yL
  189. data[var10 + 7] = 0;//yH
  190. // for(int l=0;l<8;l++){
  191. // NSInteger d =data[var10 + l];
  192. // [toLog appendFormat:@"%ld,",(long)d];
  193. // }
  194. for (int j = 0; j < nBytesPerLine; ++j) {
  195. data[var10 + 8 + j] = (int) (p0[src[k]] + p1[src[k + 1]] + p2[src[k + 2]] + p3[src[k + 3]] + p4[src[k + 4]] + p5[src[k + 5]] + p6[src[k + 6]] + src[k + 7]);
  196. k =k+8;
  197. // [toLog appendFormat:@"%ld,",(long)data[var10+8+j]];
  198. }
  199. // [toLog appendString:@"\n\r"];
  200. }
  201. // NSLog(@"line datas: %@",toLog);
  202. return [NSData dataWithBytes:data length:nHeight*(8+nBytesPerLine)];
  203. }
  204. +(unsigned char *)format_K_threshold:(unsigned char *) orgpixels
  205. width:(NSInteger) xsize height:(NSInteger) ysize
  206. {
  207. unsigned char * despixels = malloc(xsize*ysize);
  208. int graytotal = 0;
  209. int k = 0;
  210. int i;
  211. int j;
  212. int gray;
  213. for(i = 0; i < ysize; ++i) {
  214. for(j = 0; j < xsize; ++j) {
  215. gray = orgpixels[k] & 255;
  216. graytotal += gray;
  217. ++k;
  218. }
  219. }
  220. int grayave = graytotal / ysize / xsize;
  221. k = 0;
  222. // NSMutableString *logStr = [[NSMutableString alloc]init];
  223. // int oneCount = 0;
  224. for(i = 0; i < ysize; ++i) {
  225. for(j = 0; j < xsize; ++j) {
  226. gray = orgpixels[k] & 255;
  227. if(gray > grayave) {
  228. despixels[k] = 0;
  229. } else {
  230. despixels[k] = 1;
  231. // oneCount++;
  232. }
  233. ++k;
  234. // [logStr appendFormat:@"%d,",despixels[k]];
  235. }
  236. }
  237. // NSLog(@"despixels [with 1 count:%d]: %@",oneCount,logStr);
  238. return despixels;
  239. }
  240. +(NSData *)pixToTscCmd:(uint8_t *)src width:(NSInteger) width
  241. {
  242. int length = (int)width/8;
  243. uint8_t * data = malloc(length);
  244. int k = 0;
  245. for(int j = 0;k<length;++k){
  246. data[k] =(uint8_t)(p0[src[j]] + p1[src[j + 1]] + p2[src[j + 2]] + p3[src[j + 3]] + p4[src[j + 4]] + p5[src[j + 5]] + p6[src[j + 6]] + src[j + 7]);
  247. j+=8;
  248. }
  249. return [[NSData alloc] initWithBytes:data length:length];
  250. }
  251. @end